Hizmet çalışanı düşünce yapısı

Service Worker'ları düşünürken ne düşünmelisiniz?

Service Worker'lar güçlüdür ve kesinlikle öğrenmeye değerdir. Kullanıcılarınıza yepyeni bir deneyim seviyesi sunmanızı sağlar. Siteniz anında yüklenebilir. Çevrimdışı olarak çalışabilir. Platforma özel bir uygulama olarak yüklenebilir ve her yönüyle gösterişli ama web'in erişimi ve özgürlüğüyle.

Ancak Service Worker'lar, çoğu web geliştiricisinin alışkın olduğu hiçbir şeye benzemez. Yoğun bir öğrenme süreciyle karşı karşıyalar ve dikkat etmeniz gereken bazı sorunlar var.

Google Developers ile kısa bir süre önce bir projede, hizmet çalışanlarını anlamaya yönelik ücretsiz bir oyun olan Service Workies üzerinde ortak çalıştık. Bu sistemi geliştirirken ve hizmet çalışanlarının karmaşık ayrıntılarıyla çalışırken birkaç sorunla karşılaştım. Bu konuda en çok yardımcı olan, birkaç betimleyici metafor bulmak oldu. Bu gönderide, bu zihinsel modelleri keşfedecek ve hizmet çalışanlarını zorlayıcı ve müthiş bir deneyime dönüştüren paradoksal özelliklere odaklanacağız.

Aynı ancak farklı

Service Worker'ınızı kodlarken size tanıdık gelecek birçok şey vardır. En sevdiğiniz yeni JavaScript dili özelliklerini kullanabilirsiniz. Kullanıcı arayüzü etkinliklerinde olduğu gibi yaşam döngüsü olaylarını dinlersiniz. Kontrol akışını, alışkın olduğunuz gibi taahhütlerle yönetirsiniz.

Ancak diğer hizmet çalışanı davranışları kafanızın karışmasına neden olur. Özellikle sayfayı yenilediğinizde kod değişikliklerinizin uygulandığını görmüyorsanız.

Yeni katman

Normalde, bir site oluştururken düşünmeniz gereken yalnızca iki katman vardır: istemci ve sunucu. Service Worker, ortasında yer alan yepyeni bir katmandır.

Service Worker, istemci ile sunucu arasında orta katman görevi görür

Service Worker'ı, sitenizin kullanıcınızın tarayıcısına sitenizin yükleyebileceği bir tür tarayıcı uzantısı olarak düşünebilirsiniz. Uzantı yüklendikten sonra hizmet çalışanı, tarayıcıyı güçlü bir orta katmanla siteniz için extends. Bu hizmet çalışanı katmanı, sitenizin gönderdiği tüm isteklere müdahale edip bunları işleyebilir.

Service Worker katmanının tarayıcı sekmesinden bağımsız olarak kendi yaşam döngüsü vardır. Sunucuda dağıtılan kodun güncellenmesi için sayfa yenilemesinin beklemediğiniz gibi, basit bir sayfa yenilemesi de Service Worker'ı güncellemek için yeterli değildir. Her katmanın kendi güncelleme kuralları vardır.

Service Workies oyununda Service Worker'ın yaşam döngüsüyle ilgili birçok ayrıntıya değiniyor ve onunla birçok pratik yapma alıştırması yapın.

Güçlü ancak sınırlı

Sitenizde bir Service Worker'ın olması size inanılmaz avantajlar sağlar. Siteniz:

  • kullanıcı çevrimdışı olsa bile kusursuz bir şekilde çalışmak
  • Önbelleğe alma yoluyla büyük performans iyileştirmeleri elde etme
  • push bildirimlerini kullanın
  • PWA olarak yüklenmelidir.

Service Worker'ların yapabildiği kadar tasarım nedeniyle sınırlıdır. Sitenizle eşzamanlı olarak veya aynı iş parçacığında hiçbir şey yapamazlar. Bu durumda şunlara erişilemez:

  • localStorage
  • DOM
  • pencere

Neyse ki sayfanızın hizmet çalışanıyla iletişim kurabileceği, doğrudan postMessage, bire bir Mesaj Kanalları ve bire-bir çok Yayın Kanalları gibi birkaç yol vardır.

Uzun ömürlü ama kısa ömürlü

Etkin bir hizmet çalışanı, kullanıcı sitenizden ayrıldıktan veya sekmeyi kapattıktan sonra bile çalışmaya devam eder. Tarayıcı bu hizmet çalışanını, kullanıcı sitenize tekrar döndüğünde hazır olması için saklar. İlk istek yapılmadan önce Service Worker'a müdahale etme ve sayfanın kontrolünü ele geçirme fırsatı sunulur. Bu, bir sitenin çevrimdışı çalışmasına olanak tanır. Service Worker, kullanıcının internet bağlantısı olmasa bile sayfanın önbelleğe alınmış bir sürümünü sunabilir.

Service Workies bölümünde, bu kavramı Kolohe'un (yardımcı bir hizmet çalışanı) müdahale ederek isteklere müdahale ettiği ve ele aldığı görselleştirdik.

Durduruldu

Service Worker'lar ölümsüz gibi görünse de neredeyse her zaman durdurulabilir. Tarayıcı, şu anda hiçbir şey yapmayan bir hizmet çalışanı için kaynakları boşa harcamak istemiyor. Durdurulmak, sonlandırılması ile aynı şey değildir. Service Worker yüklü ve etkin durumda kalır. Sadece uyku moduna geçiriliyor. Bir sonraki gerektiğinde (ör. bir isteği işlemek için) tarayıcı bunu tekrar uyandırır.

waitUntil

Sürekli uykuya dalma olasılığı nedeniyle, hizmet çalışanınızın önemli bir şey yaptığını ve uyuyormuş gibi hissetmediğini tarayıcının bunu bilmesi için bir yönteme ihtiyacı vardır. İşte event.waitUntil() bu noktada devreye giriyor. Bu yöntem, kullanıldığı yaşam döngüsünü uzatarak hem durmasını hem de biz hazır olana kadar yaşam döngüsünün bir sonraki aşamasına geçmesini önler. Bu, önbellekleri ayarlamamız, kaynakları ağdan getirmemiz ve benzer işlemler için bize zaman kazandırır.

Bu örnek, tarayıcıya, assets önbelleği oluşturulup bir kılıç resmiyle doldurulana kadar hizmet çalışanımızın yükleme işlemini tamamlamadığını belirtir:

self.addEventListener("install", event => {
  event.waitUntil(
    caches.open("assets").then(cache => {
      return cache.addAll(["/weapons/sword/blade.png"]);
    })
  );
});

Global 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 herhangi bir genel durum kullanmamaya dikkat edin. Aksi takdirde, tekrar uyandığında ve beklediğinden farklı bir duruma sahip olduğunda üzülürsünüz.

Genel durum kullanılan ş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 kaydeder (ör. 0.13981866382421893). hasHandledARequest değişkeni de true olarak değişir. Bu noktada Service Worker bir süre boşta kaldığından tarayıcı bunu durdurur. Bir sonraki istek olduğunda Service Worker'a tekrar ihtiyaç duyulur ve tarayıcı bunu uyandırır. Komut dosyası tekrar değerlendirilir. Şimdi hasHandledARequest, false olarak sıfırlandı ve favoriteNumber adı tamamen farklı: 0.5907281835659033.

Service Worker'da, depolandı durumuna güvenemezsiniz. Ayrıca, Mesaj Kanalları gibi örneklerin oluşturulması hatalara neden olabilir: Service Worker her durduğunda/başlatıldığında yepyeni bir örnek alırsınız.

Service Workies bölüm 3'te durdurulan hizmet çalışanımızı uyandırmayı beklerken tüm renklerini kaybetmiş olarak görselleştiriyoruz.

durdurulmuş bir hizmet çalışanının görselleştirmesi

Birlikte ama ayrı

Sayfanız aynı anda yalnızca bir hizmet çalışanı tarafından kontrol edilebilir. Ancak aynı anda iki Service Worker yüklenebilir. Service Worker kodunuzda bir değişiklik yapıp sayfayı yenilediğinizde aslında Service Worker'ı düzenlemiş olmazsınız. Service Worker'lar değiştirilemez. Bunun yerine yepyeni bir video hazırlıyorsunuz. Bu yeni hizmet çalışanı (buna SW2 diyelim) yüklenecek, ancak henüz etkinleşmeyecek. Mevcut hizmet çalışanının (SW1) sonlandırılmasını (kullanıcı sitenizden ayrıldığında) beklemek gerekir.

Başka bir hizmet çalışanının önbellekleriyle karışıklık

SW2, yükleme sırasında genellikle önbellek oluşturup doldurarak ayarların yapılmasını sağlayabilir. Ama dikkat edin: 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 için işleri tamamen bozabilir. Sorun yaşamanıza 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ı atlaBekleme

Ayrıca Service Worker, yükleme işlemi tamamlanır tamamlanmaz sayfanın kontrolünü ele geçirmek için riskli skipWaiting() yöntemini de kullanabilir. Kasıtlı olarak hatalı bir hizmet çalışanını değiştirmeye çalışmadığınız sürece bu genellikle kötü bir fikirdir. Yeni Service Worker, geçerli sayfanın beklemediği şekilde güncellenmiş kaynaklar kullanıyor olabilir. Bu da hatalara ve hatalara yol açabilir.

Temizlemeye başla

Hizmet çalışanlarınızın birbirlerini bloke etmesini önlemenin yolu, farklı önbellekler kullandıklarından emin olmaktır. Bunu yapmanın en kolay yolu, kullanılan önbellek adlarının sürümlerini 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ğıtırken version öğesini, önceki Service Worker'dan tamamen ayrı bir önbellekle ihtiyaç duyduğu işlemleri yapabilmesi için güçlendirirsiniz.

önbelleğin görselleştirilmesi

Temizliği sonlandır

Service Worker'ınız activated durumuna ulaştığında hizmetin ele geçirildiğini anlarsınız ve önceki hizmet çalışanı yedeklenir. Bu noktada, eski Service Worker'dan sonra temizlik yapılması önemlidir. Bu, kullanıcılarınızın önbellek depolama alanı sınırlarına uymakla kalmaz, aynı zamanda istemeden yapılabilecek hataları da önler.

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. assets-1 ve assets-2 olmak üzere iki farklı önbellekte app.js komut dosyası 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 sitesinden eski önbelleği geri döndürecek ve büyük olasılıkla sitenizi bozacaktır.

Önceki Service Worker'ların ihtiyaç duymadığı önbelleğin silinmesinden sonra bu temizlik işleminin tek yapılması gerekir:

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 bloke etmesini önlemek için biraz çalışma ve disiplin gerekir ama zahmete değer.

Hizmet çalışanı yaklaşımı

Service Worker'lar üzerine düşünürken doğru bir zihniyet benimsemek, kendi çalışanlarınızı güvenle oluşturmanıza yardımcı olur. Bunları kavradıktan sonra kullanıcılarınız için muhteşem deneyimler oluşturabileceksiniz.

Oyun oynayarak tüm bunları anlamak istiyorsanız şanslısınız! Service Workies oyununda hizmet çalışanının çevrimdışı canavarları nasıl öldürdüğünü öğreneceksiniz.