Service Worker'ları değerlendirirken nasıl düşünülmeli?
Service Worker'lar güçlüdür ve öğrenmeye değer kılar. Kullanıcılarınıza yepyeni bir deneyim sunmanıza olanak tanırlar. Siteniz anında yüklenebilir. Çevrimdışı çalışabilir. Platforma özel bir uygulama olarak yüklenip şık bir tasarıma sahip. Hem de web'in erişimi ve özgürlüğü sayesinde.
Ancak Service Worker'lar, çoğu web geliştiricilerimizin alışkın olduğu işlere benzemez. Karmaşık bir eğitim süreci olan bu oyunda dikkat etmeniz gereken bazı sorunlar var.
Google Developers ve ben kısa süre önce, Service Worker'ları anlamaya yönelik ücretsiz bir oyun olan Service Workies'te ortak çalışma yaptık. Ürünü oluştururken ve ayrıntılı hizmet çalışanları ile çalışırken birkaç sorunla karşılaştım. Bana en çok yardımcı olan şey betimleyici metaforlar bulmaktı. Bu gönderide bu zihinsel modelleri inceleyecek ve beyinlerimizi, hizmet çalışanlarını hem ustalıklı hem de harika kılan paradoksal özelliklere çevireceğiz.
Aynı ancak farklı
Service Worker'ınızı kodlarken birçok nokta size tanıdık gelecektir. En sevdiğiniz yeni JavaScript dili özelliklerini kullanmaya başlayabilirsiniz. Kullanıcı arayüzü etkinliklerinde olduğu gibi yaşam döngüsü olaylarını dinlersiniz. Her zamanki gibi vaatlerle kontrol akışını yönetirsiniz.
Ancak Service Worker'ın diğer davranışları kafanızı karıştırarak kafanızı karıştırmanıza neden oluyor. Özellikle sayfayı yenilediğinizde ve kod değişikliklerinizin uygulanmadığını görürseniz.
Yeni bir katman
Normalde bir site oluştururken göz önünde bulundurmanız gereken yalnızca iki katman vardır: istemci ve sunucu. Service Worker, ortada bulunan yepyeni bir katmandır.
Service Worker'ı, sitenizin kullanıcı tarayıcısına yükleyebileceğiniz bir tür tarayıcı uzantısı olarak düşünebilirsiniz. Yüklendikten sonra Service Worker, güçlü bir orta katmanla sitenizin tarayıcısını genişletir. Bu hizmet çalışanı katmanı, sitenizin gönderdiği tüm isteklere müdahale edip bunları işleyebilir.
Service Worker katmanı, tarayıcı sekmesinden bağımsız olarak kendi yaşam döngüsüne sahiptir. Bir sunucuda dağıtılan kodun güncellenmesi için bir sayfanın yenilenmesini beklememeniz gibi, basit bir sayfa yenilemesi Service Worker'ı güncellemek için yeterli değildir. Her katmanın güncelleme için benzersiz kuralları vardır.
Service Workies oyununda, hizmet çalışanı yaşam döngüsüyle ilgili birçok ayrıntıyı ele alıyor ve size bu konuyla ilgili pratik alıştırmalar yapacaksınız.
Güçlü ancak sınırlı
Sitenizde bir hizmet çalışanının olması size inanılmaz avantajlar sağlar. Siteniz şunları yapabilir:
- Kullanıcı çevrimdışıyken bile sorunsuz bir şekilde çalışır
- önbelleğe alma yoluyla büyük performans iyileştirmeleri elde etme
- push bildirimlerini kullanın
- PWA olarak yüklü olmalıdır
Service Worker'lar ne kadar çok yapabilseler de bunların tasarımları sınırlıdır. Eşzamanlı olarak veya sitenizle aynı ileti dizisinde herhangi bir işlem yapamaz. Yani aşağıdakilere erişim yoktur:
- localStorage
- DOM
- pencere
İyi bir haberimiz de var. Sayfanızın hizmet çalışanıyla iletişim kurabileceği çeşitli yollar vardır. Bu yollar arasında doğrudan postMessage
, bire bir Mesaj Kanalları ve bire çok sayıda Yayın Kanalı yer alır.
Uzun ömürlü ama kısa ömürlü
Etkin bir hizmet çalışanı, bir kullanıcı sitenizden ayrıldıktan veya sekmeyi kapattıktan sonra bile yaşamaya devam eder. Tarayıcı, kullanıcı sitenize bir sonraki gelişinde hazır olması için bu hizmet çalışanını etrafta tutar. Hizmet çalışanı, ilk istek yapılmadan önce müdahale etme ve sayfanın kontrolünü ele geçirme fırsatı yakalar. Bir sitenin çevrimdışı olarak çalışmasına olanak tanıyan budur. Hizmet çalışanı, kullanıcının internet bağlantısı olmasa bile sayfanın önbelleğe alınmış bir sürümünü sunabilir.
Service Workies'de ise bu kavramı, istekleri ele alan ve ele alan Kolohe (dost canlısı bir hizmet çalışanı) ile görselleştiriyoruz.
Durduruldu
Hizmet çalışanları ölümsüz gibi görünseler de neredeyse her an durdurulabilirler. Tarayıcı, şu anda hiçbir şey yapmayan bir hizmet çalışanı için kaynakları boşa harcamak istemez. Durdurulmak feshetmekle aynı şey değildir. Service Worker'ın yüklü ve etkin durumda olduğu anlamına gelir. Uykuya alındı. Tekrar gerektiğinde (ör. bir isteği işlemek için) tarayıcı isteği yeniden uyandırır.
waitUntil
Her zaman uykuya dalma olasılığı nedeniyle, hizmet çalışanınızın önemli bir şey yaptığını ve şekerleme yapmak istemediğini tarayıcının bilmesini sağlayacak bir yönteme ihtiyacı vardır. İşte event.waitUntil()
burada devreye giriyor. Bu yöntem, kullanıldığı yaşam döngüsünü uzatarak uygulamanın hem durdurulmasını hem de yaşam döngüsünün bir sonraki aşamasına geçmesini engeller. Bu, önbellekleri kurma, ağdan kaynakları getirme vb. işlemler için bize zaman kazandırır.
Bu örnekte tarayıcıya, assets
önbelleği oluşturulup bir kılıç resmiyle doldurulana kadar hizmet çalışanımızın yüklemenin tamamlanmamış olduğu bildirilir:
self.addEventListener("install", event => {
event.waitUntil(
caches.open("assets").then(cache => {
return cache.addAll(["/weapons/sword/blade.png"]);
})
);
});
Küresel duruma dikkat edin
Bu başlatma/durdurma gerçekleştiğinde hizmet çalışanının genel kapsamı sıfırlanır. Bu nedenle, hizmet çalışanınızda hiçbir genel durumu kullanmamaya dikkat edin. Aksi takdirde, bir sonraki uyandığında ve beklediğinden farklı bir durumunda olduğunda üzülürsünüz.
Genel durumu kullanan şu örneği düşünün:
const favoriteNumber = Math.random();
let hasHandledARequest = false;
self.addEventListener("fetch", event => {
console.log(favoriteNumber);
console.log(hasHandledARequest);
hasHandledARequest = true;
});
Bu hizmet çalışanı her istekte bir numara girecektir. 0.13981866382421893
diyelim. hasHandledARequest
değişkeni de true
olarak değişir. Şimdi Service Worker bir süre boşta kaldığından tarayıcı bunu durdurur. Bir sonraki istek olduğunda Service Worker'a tekrar ihtiyaç duyulur, böylece tarayıcı bunu uyandırır. Komut dosyası tekrar değerlendirilir. Şimdi hasHandledARequest
değeri false
olarak sıfırlandı ve favoriteNumber
tamamen farklı bir değer (0.5907281835659033
).
Service Worker'da depolanan duruma güvenemezsiniz. Ayrıca, Mesaj Kanalları gibi öğelerin örneklerinin oluşturulması hatalara neden olabilir: Hizmet çalışanı her durduğunda/başladığında yepyeni bir örnek alırsınız.
Service Workies bölümü 3'te, durdurulan hizmet çalışanımızın uyanılmasını beklerken tüm renklerinin kaybolduğunu görselleştiriyoruz.
Birlikte ama ayrı
Sayfanız aynı anda yalnızca bir hizmet çalışanı tarafından kontrol edilebilir. Ancak aynı anda iki hizmet çalışanı yüklenebilir. Service Worker kodunuzda değişiklik yapıp sayfayı yenilediğinizde hizmet çalışanınızı hiç düzenlemiş olmazsınız. Service Worker'ler değişmezdir. Bunun yerine yepyeni bir kampanya oluşturuyorsunuz. Bu yeni hizmet çalışanı (SW2 olarak adlandıralım) yüklenir ancak henüz etkinleştirmez. Geçerli hizmet çalışanının (SW1) feshedilmesini (kullanıcı sitenizden ayrıldığında) beklemelidir.
Başka bir hizmet çalışanının önbellekleriyle uğraşma
SW2, yükleme sırasında kurulum işlemlerini gerçekleştirebilir. Bu işlemler genellikle önbellek oluşturur ve önbellekleri doldurur. Ancak uyarı: Bu yeni Service Worker, mevcut Service Worker'ın erişebildiği her şeye erişebilir. Dikkatli olmazsanız yeni bekleyen hizmet çalışanınız mevcut hizmet çalışanınızı mahvetebilir. Soruna neden olabilecek bazı örnekler:
- SW2, SW1'in etkin olarak kullandığı bir önbelleği silebilir.
- SW2, SW1'in kullandığı bir önbelleğin içeriğini düzenleyebilir ve bu da SW1'in sayfanın beklemediği öğelerle yanıt vermesine neden olabilir.
Atlamayı Beklemeyi Atla
Ayrıca hizmet çalışanı, yükleme işlemi tamamlanır tamamlanmaz sayfanın kontrolünü ele geçirmek için riskli skipWaiting()
yöntemini de kullanabilir. Hatalı bir servis çalışanını değiştirmeye kasten değilseniz bu genellikle kötü bir fikirdir. Yeni hizmet çalışanı, geçerli sayfanın beklemediği güncellenmiş kaynakları kullanıyor olabilir ve bu da hatalara ve hatalara yol açabilir.
Temizlemeye başla
Hizmet çalışanlarınızın birbirlerine engel oluşturmasını önlemenin yolu, farklı önbellekler kullandıklarından emin olmaktır. Bunu yapmanın en kolay yolu, kullandıkları önbellek adlarının sürümünü oluşturmaktır.
const version = 1;
const assetCacheName = `assets-${version}`;
self.addEventListener("install", event => {
caches.open(assetCacheName).then(cache => {
// confidently do stuff with your very own cache
});
});
Yeni bir hizmet çalışanı dağıttığınızda version
öğesini, önceki hizmet çalışanından tamamen ayrı bir önbellek ile ihtiyacını yapması için dokundurursunuz.
Temizliği bitir
Service Worker'ınız activated
durumuna ulaştığında, bu kullanıcının devralındığını ve önceki hizmet çalışanının yedeklendiğini anlarsınız. Bu noktada, eski hizmet çalışanının ardından yer açılması önemlidir. Ayrıca, kullanıcılarınızın istenmeyen hataları da önleyebilir.
caches.match()
yöntemi, eşleşme bulunan herhangi bir önbellekten öğe almak için sıklıkla kullanılan bir kısayoldur. Ancak önbelleklerde oluşturuldukları sırayla yinelenir. app.js
komut dosyasının assets-1
ve assets-2
olmak üzere iki farklı önbellekte iki sürümüne sahip olduğunuzu varsayalım. Sayfanız, assets-2
içinde depolanan daha yeni komut dosyasını bekliyor. Ancak eski önbelleği silmediyseniz caches.match('app.js')
, assets-1
alanındaki eski önbelleği döndürecek ve büyük olasılıkla sitenizde sorun olacaktır.
Önceki hizmet çalışanları temizlendikten sonra, yeni hizmet çalışanının ihtiyaç duymadığı tüm önbellekleri silmek yeterlidir:
const version = 2;
const assetCacheName = `assets-${version}`;
self.addEventListener("activate", event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== assetCacheName){
return caches.delete(cacheName);
}
});
);
});
);
});
Hizmet çalışanlarınızın birbirlerini engellemelerini önlemek için sıkı bir çalışma ve disiplin gerekir ama bu sıkıntıya değer.
Hizmet çalışanı yaklaşımı
Service Worker'lar üzerine düşünürken doğru düşünce yapısına sahip olmak kendi yaklaşımınızı güvenle oluşturmanıza yardımcı olacaktır. Bu özellikleri kavradıktan sonra kullanıcılarınız için mükemmel deneyimler oluşturabileceksiniz.
Tüm bunları bir oyun oynayarak anlamak istiyorsanız şanslısınız. Service Workies'i oynayarak çevrimdışı canavarları öldürmek için Service Worker'ın nasıl yapılacağını öğrenin.