çalışma kutusu-penceresi

workbox-window paketi, web sayfalarınızın içinde window bağlamında çalışması amaçlanan bir modüller grubudur. Service Worker'da çalışan diğer çalışma kutusu paketlerinin tamamlayıcısıdır.

workbox-window ürününün temel özellikleri/hedefleri şunlardır:

Çalışma kutusu-penceresi içe aktarma ve kullanma

workbox-window paketinin birincil giriş noktası Workbox sınıfıdır. Bu sınıfı CDN'mizden veya popüler JavaScript paketleme araçlarından herhangi birini kullanarak kodunuza aktarabilirsiniz.

CDN'mizi kullanma

Sitenizde Workbox sınıfını içe aktarmanın en kolay yolu CDN'mizden yararlanmaktır:

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

Bu örneğin, Workbox sınıfını yüklemek için <script type="module"> ve import ifadesinin kullanıldığını unutmayın. Eski tarayıcılarda çalışmasını sağlamak için bu kodu başka bir dile çevirmeniz gerektiğini düşünebilirsiniz, ancak bu aslında gerekli değildir.

Hizmet çalışanını destekleyen başlıca tarayıcıların tümü, yerel JavaScript modüllerini de destekler. Dolayısıyla, bu kodu herhangi bir tarayıcıya sunmak son derece uygundur (eski tarayıcılar kodu görmezden gelir).

Çalışma Kutusu'nu JavaScript paketleyicilerle yükleme

workbox-window kullanmak için hiçbir araç gerekmez ancak geliştirme altyapınız npm bağımlılıklarıyla çalışan webpack veya Rollup gibi bir paketleyici zaten içeriyorsa bunları workbox-window yüklemek için kullanabilirsiniz.

İlk adım, uygulamanızın bağımlılığı olarak workbox-window uygulamasını yüklemektir:

npm install workbox-window

Ardından, uygulamanızın JavaScript dosyalarından birinde workbox-window paket adına referans vererek import çalışma kutusunu:

import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}

Paketleyiciniz dinamik içe aktarma ifadeleri aracılığıyla kod bölmeyi destekliyorsa workbox-window koşulunu koşullu olarak yükleyebilirsiniz. Bu, sayfanızın ana paketinin boyutunu küçültmeye yardımcı olur.

Service Worker'lar, yapıları gereği progresif bir geliştirme oldukları için workbox-window oldukça küçük olsa da sitenizin temel uygulama mantığının yüklü olması gerekmez.

if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}

Gelişmiş paketleme kavramları

Service Worker'da çalışan Workbox paketlerinin aksine, package.json içindeki workbox-window main ve module alanları tarafından başvurulan derleme dosyaları ES5'e aktarılır. Bu, onları günümüzün derleme araçlarıyla uyumlu hale getirir. Bu araçlardan bazıları, geliştiricilerin node_module bağımlılıklarının herhangi bir şeyi aktarmasına izin vermez.

Derleme sisteminiz bağımlılıklarınızı aktarmanıza izin veriyorsa (veya herhangi bir kodunuzu aktarmanız gerekmiyorsa) paketin kendisi yerine belirli bir kaynak dosyayı içe aktarmak daha iyidir.

Aşağıda, Workbox dosyasını içe aktarabileceğiniz çeşitli yollar ve her birinin döndüreceği sonuçların açıklaması bulunmaktadır:

// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');

// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';

// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';

Örnekler

Workbox sınıfını içe aktardıktan sonra bu sınıfı kullanarak kayıt olabilir ve hizmet çalışanınızla etkileşimde bulunabilirsiniz. Aşağıda, uygulamanızda Workbox nasıl kullanılabileceğinize dair bazı örnekler verilmiştir:

Service Worker kaydetme ve Service Worker etkin olduğunda kullanıcıya bildirim gönderme

Birçok web uygulaması, sonraki sayfa yüklemelerinde çevrimdışı çalışması için öğeleri önbelleğe almak üzere hizmet çalışanı kullanır. Bazı durumlarda, kullanıcıyı uygulamanın artık internet bağlantısı olmadan kullanılabileceğini bildirmek mantıklı olabilir.

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // `event.isUpdate` will be true if another version of the service
  // worker was controlling the page when this version was registered.
  if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

    // If your service worker is configured to precache assets, those
    // assets should all be available now.
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Bir hizmet çalışanı yüklendiyse ancak etkinleştirilmek için takılı kaldıysa kullanıcıyı bilgilendir

Mevcut bir hizmet çalışanı tarafından kontrol edilen bir sayfa yeni bir hizmet çalışanı kaydettiğinde, varsayılan olarak ilk Service Worker tarafından kontrol edilen tüm istemciler tamamen kaldırılıncaya kadar bu hizmet çalışanı etkinleştirilmez.

Bu durum, özellikle mevcut sayfanın yeniden yüklenmesinin yeni Service Worker'ın etkinleştirilmesine neden olmadığı durumlarda geliştiriciler için yaygın olarak kafa karışıklığı yaratır.

Karışıklığı en aza indirmek ve bu durumun ne zaman gerçekleştiğini netleştirmek için Workbox sınıfı, izleyebileceğiniz bir waiting etkinliği sunar:

const wb = new Workbox('/sw.js');

wb.addEventListener('waiting', event => {
  console.log(
    `A new service worker has installed, but it can't activate` +
      `until all tabs running the current version have fully unloaded.`
  );
});

// Register the service worker after event listeners have been added.
wb.register();

workbox-broadcast-update paketindeki önbellek güncellemelerini kullanıcıya bildir

workbox-broadcast-update Paket, önbellekteki içerikleri sunmanın (hızlı teslim için) yanı sıra kullanıcıya bu içerik güncellemeleri hakkında bilgi vermenin (stale- kaba-yeniden doğrulama stratejisini<br">kullanarak) mükemmel bir yoludur.

Bu güncellemeleri pencereden almak için CACHE_UPDATED türündeki message etkinliklerini dinleyebilirsiniz:

const wb = new Workbox('/sw.js');

wb.addEventListener('message', event => {
  if (event.data.type === 'CACHE_UPDATED') {
    const {updatedURL} = event.data.payload;

    console.log(`A newer version of ${updatedURL} is available!`);
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Service Worker'a önbelleğe alınacak URL'ler listesi gönderin

Bazı uygulamalar için, derleme sırasında önceden önbelleğe alınması gereken tüm öğeleri bilmek mümkündür. Ancak bazı uygulamalar, kullanıcının ilk olarak ulaştığı URL'ye bağlı olarak tamamen farklı sayfalar sunar.

İkinci kategorideki uygulamalarda, yalnızca kullanıcının ziyaret ettiği belirli sayfa için ihtiyaç duyduğu öğeleri önbelleğe almak mantıklı olabilir. workbox-routing paketini kullanırken yönlendiricinize önbelleğe alınacak URL'lerin listesini gönderebilirsiniz. Bu liste, bu URL'leri yönlendiricinin kendisinde tanımlanan kurallara göre önbelleğe alır.

Bu örnekte, yeni bir Service Worker etkinleştirildiğinde sayfa tarafından yüklenen URL'lerin listesi yönlendiriciye gönderilir. Yalnızca Service Worker'da tanımlanmış bir rotayla eşleşen URL'ler önbelleğe alınacağından, tüm URL'ler gönderilebilir:

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // Get the current page URL + all resources the page loaded.
  const urlsToCache = [
    location.href,
    ...performance.getEntriesByType('resource').map(r => r.name),
  ];
  // Send that list of URLs to your router in the service worker.
  wb.messageSW({
    type: 'CACHE_URLS',
    payload: {urlsToCache},
  });
});

// Register the service worker after event listeners have been added.
wb.register();

Service Worker'ın önemli yaşam döngüsü anları

Hizmet çalışanı yaşam döngüsü karmaşıktır ve tam olarak anlaşılmasını zorlaştırabilir. Bu kadar karmaşık olmasının bir nedeni de Service Worker'ın olası tüm kullanımları için (ör. birden fazla Service Worker kaydetme, farklı çerçevelere farklı hizmet çalışanlarını kaydetme, Service Worker'ları farklı adlarla kaydetme vb.) tüm uç durumlarla ilgilenmesidir.

Ancak, Service Worker'ı uygulayan çoğu geliştiricinin kullanımı son derece basit olduğu için tüm bu uç durumlar konusunda endişelenmesi gerekmez. Çoğu geliştirici, sayfa başına yalnızca bir hizmet çalışanı kaydeder ve sunucusuna dağıttığı Service Worker dosyasının adını değiştirmez.

Workbox sınıfı, tüm Service Worker kayıtlarını iki kategoriye ayırarak hizmet çalışanı yaşam döngüsü için bu daha basit görünümü benimser: örneğin ait, kayıtlı hizmet çalışanı ve harici hizmet çalışanı:

  • Kayıtlı hizmet çalışanı: register() çağrısı yapan Workbox örneğinin veya register() çağrısı kayıtta bir updatefound etkinliğini tetiklemediyse zaten etkin olan Service Worker'ın sonucu olarak yüklemeye başlayan hizmet çalışanı.
  • Harici hizmet çalışanı: register() çağrısı yapan Workbox örneğinden bağımsız olarak yükleme yapmaya başlayan hizmet çalışanı. Bu durum genellikle, kullanıcı sitenizin yeni bir sürümünü başka bir sekmede açtığında ortaya çıkar. Bir etkinlik harici bir hizmet çalışanından kaynaklandığında, etkinliğin isExternal özelliği true olarak ayarlanır.

Bu iki hizmet çalışanı türü düşünüldüğünde, tüm önemli Service Worker yaşam döngüsü anlarının dökümü ve bunların nasıl ele alınacağına dair geliştirici önerileri aşağıda verilmiştir:

Service Worker ilk kez yüklendiğinde

Muhtemelen bir Service Worker'ın ilk yükleme işlemi, gelecekteki tüm güncellemeleri ele aldığınızdan farklı olacaktır.

workbox-window ürününde, aşağıdaki etkinliklerin herhangi birinde isUpdate özelliğini kontrol ederek ilk sürüm yüklemesi ile gelecekteki güncellemeleri birbirinden ayırt edebilirsiniz. İlk yükleme için isUpdate değeri false olur.

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', event => {
  if (!event.isUpdate) {
    // First-installed code goes here...
  }
});

wb.register();
Etkinlik Etkinlik Önerilen işlem
Yeni bir hizmet çalışanı yüklendi (ilk kez) installed

Bir hizmet çalışanı ilk kez yüklediğinde, sitenin çevrimdışı çalışması için gereken tüm öğelerin önbelleğe alınması yaygındır. Kullanıcıyı, sitesinin artık çevrimdışı olarak çalışabileceği konusunda bilgilendirebilirsiniz.

Ayrıca, bir hizmet çalışanı ilk kez yüklediğinde söz konusu sayfa yüklemesinde getirme etkinliklerine müdahale etmeyeceğinden, önceden yüklenmiş öğeleri önbelleğe almayı da düşünebilirsiniz (bu öğeler zaten önceden önbelleğe alınıyorsa bu gerekli değildir). Yukarıdaki hizmet çalışanına önbelleğe alınacak URL'lerin listesini gönderme örneği, bunun nasıl yapılacağını gösterir.

Service Worker sayfayı kontrol etmeye başladı controlling

Yeni bir hizmet çalışanı yüklenip sayfayı kontrol etmeye başladığında sonraki tüm getirme etkinlikleri bu hizmet çalışanı üzerinden geçer. Service Worker'ınız belirli bir getirme etkinliğini işlemek için özel bir mantık eklerse mantığın çalışacağını anladığınız nokta burasıdır.

Service Worker'ı ilk kez yüklediğinizde, bu hizmet çalışanı etkinleştirme etkinliğinde clients.claim() çağrısını yapmadığınız sürece geçerli sayfayı kontrol etmeye başlamayacağını unutmayın. Varsayılan davranış, kontrole başlamak için sonraki sayfanın yüklenmesini beklemektir.

workbox-window açısından bu, controlling etkinliğinin yalnızca hizmet çalışanının clients.claim() çağırdığı durumlarda gönderileceği anlamına gelir. Sayfa, kayıttan önce zaten denetlenmişse bu etkinlik gönderilmez.

Service Worker'ın etkinleştirilmesi tamamlandı activated

Yukarıda belirtildiği gibi, bir hizmet çalışanının etkinleştirme işlemini tamamladığı ilk seferde sayfa kontrol edilmeye başlamış olabilir (veya başlamamış olabilir).

Bu nedenle, hizmet çalışanının sayfa kontrolünde olduğunu anlamanın bir yolu olarak etkinleştirme etkinliğini dinlememelisiniz. Ancak aktif etkinlikte (Service Worker'da) mantığı çalıştırıyorsanız ve bu mantığın ne zaman tamamlandığını öğrenmeniz gerekiyorsa etkinleştirilen etkinlik bunu size bildirir.

Service Worker'ın güncel bir sürümü bulunduğunda

Yeni bir hizmet çalışanı yüklemeye başladığında, ancak sayfayı mevcut bir sürüm kontrol ediyorsa aşağıdaki tüm etkinliklerin isUpdate özelliği true olur.

Kullanıcının bu güncellemeyi ne zaman ve nasıl alacağını yönetmeniz gerektiğinden, bu durumda nasıl tepki vereceğiniz genellikle ilk yüklemeden farklıdır.

Etkinlik Etkinlik Önerilen işlem
Yeni bir hizmet çalışanı yüklendi (önceki bir hizmet çalışanı güncelleniyor) installed

Bu, ilk Service Worker yüklemesi (event.isUpdate === true) değilse Service Worker'ın daha yeni bir sürümünün (yani, sayfayı şu anda kontrol eden sürümden farklı bir sürüm) bulunduğu ve yüklendiği anlamına gelir.

Bu genellikle sitenin daha yeni bir sürümünün sunucunuza dağıtıldığı ve yeni öğelerin önbelleğe alma işleminin yeni bitmiş olabileceği anlamına gelir.

Not: Bazı geliştiriciler, kullanıcılara sitelerinin yeni bir sürümünün olduğunu bildirmek için installed etkinliğini kullanır. Ancak, yüklenen hizmet çalışanının skipWaiting() yöntemini çağırıp çağırmadığınıza bağlı olarak söz konusu yüklenen hizmet çalışanı hemen etkin hale gelebilir veya olmayabilir. skipWaiting() yöntemini çözüyorsanız yeni hizmet çalışanı etkinleştirildikten sonra kullanıcıları güncelleme konusunda bilgilendirmeniz önerilir. skipWaiting numaralı telefonu aramazsanız, bekleme etkinliğindeki bekleyen güncelleme hakkında onlara bilgi vermek daha iyi olacaktır (ayrıntılı bilgi için aşağıya göz atın).

Bir hizmet çalışanı yüklendi, ancak bekleme aşamasında takılı kaldı waiting

Service Worker'ınızın güncellenmiş sürümü yüklenirken skipWaiting() yöntemini çağırmazsa etkin durumda olan Service Worker tarafından kontrol edilen tüm sayfalar kaldırılıncaya kadar etkinleştirilmez. Kullanıcıyı bir güncellemenin olduğunu ve bir sonraki ziyaretinde uygulanacağını bildirebilirsiniz.

Uyarı! Geliştiricilerin, güncellemeyi almak için kullanıcılardan sayfayı yeniden yüklemelerini istemeleri sık karşılaşılan bir durumdur, ancak çoğu durumda sayfayı yenilemek yüklü çalışanı etkinleştirmez. Kullanıcı sayfayı yenilerse ve hizmet çalışanı hâlâ bekliyorsa waiting etkinliği tekrar etkinleşir ve event.wasWaitingBeforeRegister özelliği doğru olur. Gelecekteki bir sürümde bu deneyimi iyileştirmeyi planlıyoruz. Güncellemeler için #1848 numaralı sorunu takip edin.

Diğer bir seçenek de kullanıcıya güncellemeyi almak mı yoksa beklemeye devam etmek mi istediğini sormaktır. Güncellemeyi almayı tercih ederseniz postMessage() öğesini kullanarak hizmet çalışanına skipWaiting() uygulamasını çalıştırmasını söyleyebilirsiniz. Bunun bir örneğini, kullanıcılar için sayfayı yeniden yükleme olanağı sunma başlıklı gelişmiş tarifede inceleyebilirsiniz.

Service Worker sayfayı kontrol etmeye başladı controlling

Güncellenmiş bir Service Worker'ın sayfayı kontrol etmeye başlaması, şu anda kontrol eden Service Worker'ın, sayfa yüklendiğinde kontrol edilen sürümden farklı olduğu anlamına gelir. Bazı durumlarda bu bir sorun teşkil etmese de bu durum, geçerli sayfanın başvuruda bulunduğu bazı öğelerin artık önbellekte olmadığı (ve muhtemelen sunucuda da bulunmadığı) anlamına gelebilir. İsterseniz sayfanın bazı bölümlerinin düzgün çalışmayabileceğini kullanıcıya bildirebilirsiniz.

Not: Service Worker'ınızda skipWaiting() çağrısı yapmazsanız controlling etkinliği tetiklenmez.

Service Worker'ın etkinleştirilmesi tamamlandı activated Güncellenen bir hizmet çalışanı etkinleştirmeyi bitirdiğinde bu, hizmet çalışanının activate işlevinde çalıştırmakta olduğunuz tüm mantığın tamamlandığı anlamına gelir. Bu mantık tamamlanıncaya kadar ertelemeniz gereken herhangi bir şey varsa çalıştırmanın zamanı gelmiştir.

Service Worker'ın beklenmeyen bir sürümü bulunduğunda

Bazen kullanıcılar sitenizi arka plandaki bir sekmede uzun süre açık tutar. Hatta, sitenizin arka plandaki bir sekmede açık olduğunun farkında yeni bir sekme açıp sitenize gidebilir. Bu gibi durumlarda, sitenizin iki sürümünün aynı anda çalışır durumda olması mümkündür. Bu da geliştirici olarak sizin için bazı ilginç sorunlar oluşturabilir.

Sitenizin A sekmesinin v1, B sekmesinin ise v2 sürümünün olduğu bir senaryo düşünün. B sekmesi yüklendiğinde, hizmet çalışanınızın v1 ile gönderen sürümü tarafından kontrol edilir ancak sunucunun döndürdüğü sayfa (gezinme istekleriniz için ağ öncelikli önbelleğe alma stratejisi kullanılıyorsa) tüm v2 öğelerinizi içerir.

Ancak bu genellikle B sekmesi için bir soruna yol açmaz. Çünkü v2 kodunuzu yazdığınızda v1 kodunuzun nasıl çalıştığını biliyordunuz. Ancak bu durum, v1 kodunuz v2 kodunuzda meydana gelecek değişiklikleri tahmin edemediğinden A sekmesi için bir sorun olabilir.

Bu durumların üstesinden gelmek için workbox-window, "harici" bir hizmet çalışanından gelen bir güncelleme algıladığında yaşam döngüsü olaylarını da gönderir. "Harici", yalnızca mevcut Workbox örneğinde kayıtlı olmayan tüm sürümler anlamına gelir.

Workbox v6 ve sonraki sürümlerde bu etkinlikler, her bir etkinlik nesnesinde ayarlanmış bir isExternal: true özelliği eklenerek yukarıda belirtilen etkinliklere eşdeğerdir. Web uygulamanızın "harici" bir hizmet çalışanını işlemek için belirli bir mantığı uygulaması gerekiyorsa etkinlik işleyicilerinizden bu mülkü kontrol edebilirsiniz.

Yaygın hatalardan kaçınma

Workbox'ın sağladığı en yararlı özelliklerden biri, geliştirici günlük kaydıdır. Bu, özellikle workbox-window için geçerli.

Service Worker ile geliştirmenin genellikle kafa karıştırıcı olabileceğinin ve beklediğinizin dışında işler olduğunda bunun nedenini bilmek zor olabileceğinin farkındayız.

Örneğin, hizmet çalışanınızda bir değişiklik yapıp sayfayı yeniden yüklediğinizde bu değişikliği tarayıcınızda göremeyebilirsiniz. Bunun en olası nedeni, hizmet çalışanınızın hâlâ etkinleştirilmeyi beklemesidir.

Ancak bir hizmet çalışanını Workbox sınıfına kaydederken geliştirici konsolunda yaşam döngüsündeki tüm değişiklikler hakkında bilgilendirilirsiniz. Bu da, işlerin beklediğiniz gibi olmamasına yol açan hataları ayıklamanıza yardımcı olur.

Çalışan için çalışma kutusu penceresi konsol uyarısı

Ayrıca geliştiricilerin Service Worker'ı ilk kez kullanırken yaptıkları yaygın bir hata, Service Worker'ı yanlış kapsamda kaydetmektir.

Bunun olmasını önlemek için Workbox sınıfı, Service Worker'ı kaydeden sayfa söz konusu hizmet çalışanının kapsamında değilse sizi uyarır. Ayrıca, Service Worker'ınızın etkin olduğu ancak sayfayı henüz kontrol etmediği durumlarda da sizi uyarır:

Denetimsiz çalışan için çalışma kutusu penceresi konsol uyarısı

Pencereden hizmete hizmet çalışanı iletişimi

Gelişmiş Service Worker kullanımının çoğu, Service Worker ile pencere arasında çok sayıda mesaj içerir. Workbox sınıfı bu konuda da yardımcı olur. Bunun için örneğin kayıtlı hizmet çalışanının postMessage() yanıt bekleyen messageSW() yöntemini sağlar.

Service Worker'a verileri dilediğiniz biçimde gönderebilirsiniz ancak tüm Workbox paketleri tarafından paylaşılan biçim, üç özelliği olan bir nesnedir (son ikisi isteğe bağlıdır):

Özellik Zorunlu mu? Tür Açıklama
type Yes string

Bu iletiyi tanımlayan benzersiz bir dize.

Kural olarak, türlerin tümü büyük harflidir ve bunları birbirinden alt çizgilere ayırır. Tür, yapılacak bir işlemi temsil ediyorsa şimdiki zamanda (ör. CACHE_URLS) bir komut olmalıdır. Tür, rapor edilen bilgiyi temsil ediyorsa geçmiş zaman (ör. URLS_CACHED) olmalıdır.

meta no string Workbox'ta bu her zaman mesajı gönderen Workbox paketinin adıdır. Kendiniz mesaj gönderirken bu özelliği atlayabilir veya istediğiniz değere ayarlayabilirsiniz.
payload no * Gönderilen veriler. Genellikle bu bir nesnedir, ancak olması zorunlu değildir.

messageSW() yöntemiyle gönderilen mesajlar, alıcının yanıt verebilmesi için MessageChannel kullanır. Bir mesajı yanıtlamak için mesaj etkinliği işleyicinizde event.ports[0].postMessage(response) yöntemini çağırabilirsiniz. messageSW() yöntemi, yanıt verdiğiniz her response için çözümlenecek sözü döndürür.

Pencereden Service Worker'a mesaj gönderip yanıt almayla ilgili bir örneği aşağıda bulabilirsiniz. İlk kod bloğu, Service Worker'daki mesaj dinleyicidir. İkinci blok ise mesajı göndermek ve yanıtı beklemek için Workbox sınıfını kullanır.

sw.js'deki kod:

const SW_VERSION = '1.0.0';

addEventListener('message', event => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

main.js'deki kod (pencerede çalışıyor):

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

Sürüm uyumsuzluklarını yönetme

Yukarıdaki örnekte, hizmet çalışanı sürümünü pencereden kontrol etmeyi nasıl uygulayabileceğiniz gösterilmektedir. Bu örneğin, pencere ve Service Worker arasında mesaj gönderirken, hizmet çalışanınızın sayfa kodunuzun çalıştırdığı sürümle aynı sürümü çalıştırmıyor olabileceğinin dikkate alınması kritik önem taşıdığı ve bu sorunu çözmenin çözümü, sayfalarınızın ağ öncelikli mi yoksa önbellek öncelikli mi olduğuna bağlı olarak farklılık gösterebileceği için kullanılır.

Önce ağ

Sayfalar ağınızı ilk olarak sunarken, kullanıcılarınız her zaman sunucunuzdan HTML'nizin en son sürümünü alırlar. Bununla birlikte, bir kullanıcı sitenizi ilk kez ziyaret ettiğinde (bir güncelleme dağıttıktan sonra) alacağı HTML en son sürüm için olur, ancak tarayıcısında çalışan hizmet çalışanı, daha önce yüklenmiş bir sürüm olur (muhtemelen birçok sürümü eskidir).

Bu olasılığı anlamak önemlidir. Çünkü sayfanızın geçerli sürümü tarafından yüklenen JavaScript, Service Worker'ınızın eski bir sürümüne mesaj gönderirse söz konusu sürüm nasıl yanıt vereceğini bilemeyebilir (veya uyumsuz bir biçimle yanıt verebilir).

Bu nedenle, kritik düzeyde çalışma yapmadan önce her zaman Service Worker için sürüm oluşturmak ve uyumlu sürümleri kontrol etmek iyi bir fikirdir.

Örneğin, yukarıdaki kodda, messageSW() çağrısının döndürdüğü Service Worker sürümü, beklenen sürümden daha eskiyse güncelleme bulunana kadar (bu, register() çağrısı yaptığınızda olması gerekir) beklemek akıllıca olacaktır. Bu noktada kullanıcıyı bilgilendirebilir ya da güncelleme yapabilir veya yeni Service Worker'ı hemen etkinleştirmek için manuel olarak bekleme aşamasını atlayabilirsiniz.

Önce önbelleğe alın

Sayfaları ağ öncelikli olarak sunduğunuzda aksine, sayfalarınızı önbelleğe öncelikli olarak sunarken sayfanızın başlangıçta her zaman hizmet çalışanınızla aynı sürüm olacağını bilirsiniz (çünkü bu, hizmet çalışanınızla aynı sürüm olacaktır). Bu nedenle, messageSW() güvenle hemen kullanılabilir.

Ancak sayfanız register() çağrısı yaptığında hizmet çalışanınızın güncellenmiş bir sürümü bulunur ve etkinleştirilirse (yani, bekleme aşamasını bilerek atlarsanız) artık bu sayfaya mesaj göndermek güvenli olmayabilir.

Bu olasılığı yönetmek için yararlanabileceğiniz stratejilerden biri, zarar veren ve bölünmeyen güncellemeleri birbirinden ayırt etmenize olanak tanıyan sürüm oluşturma şeması kullanmaktır. Böyle bir durumda, bozulan güncelleme durumunda Service Worker'a mesaj göndermenin güvenli olmadığını bilirsiniz. Bunun yerine, kullanıcıyı sayfanın eski bir sürümünü çalıştırdığı konusunda uyarabilir ve güncellemeyi alabilmesi için sayfayı yeniden yüklemesini önerebilirsiniz.

Bekleme yardımcısını atla

Pencereden hizmet çalışanı mesajlaşmasına yönelik yaygın bir kullanım kuralı, yüklü bir hizmet çalışanına bekleme aşamasını atlayıp etkinleştirme talimatı vermek için bir {type: 'SKIP_WAITING'} mesajı göndermektir.

Workbox v6'dan itibaren messageSkipWaiting() yöntemi, bekleyen hizmet çalışanına geçerli Service Worker kaydıyla ilişkili bir {type: 'SKIP_WAITING'} mesajı göndermek için kullanılabilir. Bekleyen bir Service Worker yoksa otomatik olarak hiçbir şey yapmaz.

Türler

Workbox

Service Worker kaydı, güncellemeleri ve Service Worker'ın yaşam döngüsü etkinliklerine tepki vermeyi ele alan bir sınıf.

Özellikler

  • oluşturucu

    void

    Komut dosyası URL'si ve Service Worker seçenekleriyle yeni bir Workbox örneği oluşturur. Komut dosyası URL'si ve seçenekleri, navigator.serviceWorker.register(scriptURL, options) çağrılırken kullanılanlarla aynıdır.

    constructor işlevi şu şekilde görünür:

    (scriptURL: string|TrustedScriptURL,registerOptions?: object)=> {...}

    • scriptURL

      dize|TrustedScriptURL

      Bu örnekle ilişkilendirilmiş olan Service Worker komut dosyasıdır. TrustedScriptURL kullanımı desteklenir.

    • registerOptions

      isteğe bağlı

  • etkin

    Promise<ServiceWorker>

  • kontrol ediyor

    Promise<ServiceWorker>

  • getSW

    void

    Kullanılabilir olduğunda bu örneğin komut dosyası URL'si ile eşleşen bir Service Worker referansıyla çözümlenir.

    Kayıt sırasında, eşleşen komut dosyası URL'sine sahip aktif veya bekleyen bir hizmet çalışanı varsa bu hizmet çalışanı kullanılır (beklemedeki hizmet çalışanı daha yakın zamanda kaydedileceği için bekleyen hizmet çalışanı her iki eşleşme de etkin hizmet çalışanına göre öncelikli olacaktır). Kayıt sırasında eşleşen etkin veya bekleyen hizmet çalışanı yoksa güncelleme bulunana ve yüklemeye başlayana kadar söz konusu çözüm bulunmaz ve bu noktada yükleme Service Worker kullanılır.

    getSW işlevi şu şekilde görünür:

    ()=> {...}

    • returns

      Promise<ServiceWorker>

  • messageSW

    void

    İletilen veri nesnesini bu örnek tarafından kaydedilen hizmet çalışanına gönderir (workbox-window.Workbox#getSW aracılığıyla) ve bir yanıtla (varsa) çözümlenir.

    Service Worker'daki bir mesaj işleyicide event.ports[0].postMessage(...) çağrısı yapılarak bir yanıt ayarlanabilir. Bu işlem, messageSW() tarafından verilen sözü çözümler. Yanıt ayarlanmazsa taahhüt hiçbir zaman çözüme kavuşturulmaz.

    messageSW işlevi şu şekilde görünür:

    (data: object)=> {...}

    • veri

      nesne

      Service Worker'a gönderilecek nesne

    • returns

      Söz<herhangi>

  • messageSkipWaiting

    void

    Geçerli kayıtla ilişkili waiting durumunda olan hizmet çalışanına bir {type: 'SKIP_WAITING'} mesajı gönderir.

    Mevcut bir kayıt yoksa veya hizmet çalışanı waiting değilse bunun çağrılması etkili olmaz.

    messageSkipWaiting işlevi şu şekilde görünür:

    ()=> {...}

  • register

    void

    Bu örnek komut dosyası URL'si ve hizmet çalışanı seçenekleri için bir hizmet çalışanı kaydeder. Varsayılan olarak bu yöntem, kaydı pencere yüklenene kadar erteler.

    register işlevi şu şekilde görünür:

    (options?: object)=> {...}

    • seçenekler

      isteğe bağlı

      • hemen

        boole isteğe bağlı

    • returns

      Promise<ServiceWorkerRegistration>

  • update

    void

    Kayıtlı hizmet çalışanının güncellemelerini kontrol eder.

    update işlevi şu şekilde görünür:

    ()=> {...}

    • returns

      Promise<void>

WorkboxEventMap

Özellikler

WorkboxLifecycleEvent

Özellikler

  • isExternal

    boole isteğe bağlı

  • isUpdate

    boole isteğe bağlı

  • originalEvent

    Etkinlik isteğe bağlı

  • sw

    ServiceWorker isteğe bağlı

  • hedef

    WorkboxEventTarget isteğe bağlı

  • tür

    typeOperator

WorkboxLifecycleEventMap

Özellikler

WorkboxLifecycleWaitingEvent

Özellikler

  • isExternal

    boole isteğe bağlı

  • isUpdate

    boole isteğe bağlı

  • originalEvent

    Etkinlik isteğe bağlı

  • sw

    ServiceWorker isteğe bağlı

  • hedef

    WorkboxEventTarget isteğe bağlı

  • tür

    typeOperator

  • wasWaitingBeforeRegister

    boole isteğe bağlı

WorkboxMessageEvent

Özellikler

  • veri

    Tümü

  • isExternal

    boole isteğe bağlı

  • originalEvent

    Etkinlik

  • ports

    typeOperator

  • sw

    ServiceWorker isteğe bağlı

  • hedef

    WorkboxEventTarget isteğe bağlı

  • tür

    "message"

Yöntemler

messageSW()

workbox-window.messageSW(
  sw: ServiceWorker,
  data: object,
)

postMessage aracılığıyla hizmet çalışanına bir veri nesnesi gönderir ve bir yanıtla (varsa) çözümlenir.

Service Worker'daki bir mesaj işleyicide event.ports[0].postMessage(...) çağrısı yapılarak bir yanıt ayarlanabilir. Bu işlem, messageSW() tarafından verilen sözü çözümler. Yanıt verilmezse vaat edilen sonuca ulaşmaz.

Parametreler

  • sw

    ServiceWorker

    İletinin gönderileceği hizmet çalışanı.

  • veri

    nesne

    Service Worker'a gönderilecek nesne.

İlerlemeler

  • Söz<herhangi>