Arka Plan Getirme ile tanışın

Jake Archibald
Jake Archibald

2015'te, arka plan senkronizasyonu gibi özellikler içeren Arka Plan Senkronizasyonu'nu kullanıma sunduk hizmet çalışanının işi, kullanıcı bağlantıya sahip olana kadar ertelemesine yardımcı olur. Bu, kullanıcının mesajı gönderin, Gönder'e basın ve mesajın şimdi veya anında gönderileceğini gerekir.

Faydalı bir özelliktir ancak hizmet çalışanının getir. Bu, mesaj göndermek gibi kısa süreli işler için sorun değil. çok uzun sürmesi durumunda, hizmet çalışanı sonlandırılır. Aksi halde bu, kullanıcının gizliliği pil.

Peki ya film, podcast ya da podcast gibi uzun sürebilecek bir içeriği olduğunu unutmayın. Arka Planda Getirme bu amaçla kullanılır.

Arka planda getirme özelliği, Chrome 74 sürümünden itibaren varsayılan olarak kullanılabilmektedir.

Arka Planda Getirme'nin kullanımıyla ilgili geleneksel durumu gösteren iki dakikalık kısa bir demoyu burada bulabilirsiniz:

Demoyu kendiniz deneyin ve koda göz atın.

İşleyiş şekli

Arka planda getirme şu şekilde çalışır:

  1. Tarayıcıya arka planda bir grup getirme işlemi gerçekleştirmesini söylersiniz.
  2. Tarayıcı bu öğeleri alarak ilerleme durumunu kullanıcıya gösterir.
  3. Getirme işlemi tamamlandığında veya başarısız olduğunda tarayıcı hizmet çalışanınızı açar ve bir etkinlik tetikler. ne olduğunu anlatabilirim. Yanıtlarla (varsa) ne yapacağınıza burada karar verirsiniz.

Kullanıcı 1. adımdan sonra sitenizin sayfalarını kapatırsa sorun değil, indirme işlemi devam eder. Çünkü getirme işlemi son derece görünür ve kolayca iptal edilebilir. Gizlilikle ilgili çok uzun bir süre arka plan senkronizasyon görevi. Service Worker sürekli çalışmadığı için sorun yok. sistemi kötüye kullanabileceğini biliyorsunuz (örneğin, arka planda bitcoin madenciliği yapıyor olabilir).

Bazı platformlarda (ör. Android) tarayıcı 1. adımdan sonra kapanmayabilir. Bunun nedeni tarayıcı, getirme işlemini işletim sistemine devredebilir.

Kullanıcı indirme işlemini çevrimdışıyken başlatırsa veya indirme sırasında çevrimdışı olursa arka plan duraklatılıp daha sonra devam ettirilecek.

API

Özellik algılama

Her yeni özellikte olduğu gibi, tarayıcının bu özelliği destekleyip desteklemediğini tespit etmek istersiniz. Arka Planda Getirme için en az şu kadar basit:

if ('BackgroundFetchManager' in self) {
  // This browser supports Background Fetch!
}

Arka planda getirme başlatma

Ana API, bir Service Worker kaydını geciktirir. Bu nedenle, önce bir hizmet çalışanı kaydettiğinizden emin olun. Ardından:

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
    title: 'Episode 5: Interesting things.',
    icons: [{
      sizes: '300x300',
      src: '/ep-5-icon.png',
      type: 'image/png',
    }],
    downloadTotal: 60 * 1024 * 1024,
  });
});
.

backgroundFetch.fetch, üç bağımsız değişken alır:

Parametreler
id string
bu arka plan getirme işlemini benzersiz bir şekilde tanımlar.

Kimlik mevcut bir arka planla eşleşirse backgroundFetch.fetch işlemi reddeder getir.

requests Array<Request|string>.
Getirilecek öğeler. Dizeler URL olarak işlenir ve new Request(theString) üzerinden Request.

Kaynaklar izin verdiği sürece diğer kaynaklardan öğe getirebilirsiniz. CORS.

Not: Chrome şu anda CORS ön kontrolü gerektirir.

options Şunları içerebilen bir nesne:
options.title string
İlerlemeyle birlikte tarayıcı için bir başlık.
options.icons Array<IconDefinition>
"src", "size" ve "type" içeren nesne dizisi.
options.downloadTotal number
Yanıt gövdelerinin toplam boyutu (gzip açıldıktan sonra).

İsteğe bağlı olsa da bu seçeneği sunmanız önemle tavsiye edilir. Anlatmak için kullanılır indirmenin büyüklüğünü ve ilerlemeyle ilgili bilgi verilmesini sağlar. Önce bir buna göre, tarayıcı kullanıcıya boyutun bilinmediğini söyler. Sonuç olarak kullanıcı boyutu daha büyük olabilir. indirme işlemini iptal edebilir.

Arka planda getirme indirme işlemleri burada verilen sayıyı aşarsa işlem iptal edilir. İnsanların indirme boyutu downloadTotal boyutundan küçükse hiç sorun olmaz. emin olun. Ancak, tedbiri elden bırakmamak en iyisidir.

backgroundFetch.fetch, BackgroundFetchRegistration ile çözümlenen bir taahhüt döndürür. Ben daha sonra değineceğiz. Kullanıcı indirmeleri devre dışı bırakırsa veya bir parametresinden tanesi geçersiz.

Tek bir arka plan getirme işlemi için çok sayıda istek sağlamak, mantıksal olarak tek bir şey olarak ortaya koyabilir. Örneğin, bir film binlerce kaynağa bölünebilir (genellikle MPEG-DASH), ve resimler gibi ek kaynaklarla birlikte çalışmak. Bir oyunun belirli bir seviyesi, çok sayıda kullanıcıya yayılabilir JavaScript, resim ve ses kaynakları. Ancak kullanıcı için önemli olan sadece "film" veya "seviye"dir.

Mevcut bir arka planda getirme alma

Şu şekilde mevcut bir arka plan getirme işlemi alabilirsiniz:

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});

...istediğiniz arka plan getirmenin id değerini ileterek. get, şu olmazsa undefined değerini döndürür: arka planda getirme özelliği etkin olmalıdır.

Arka planda getirme "etkin" olarak kabul edilir ve bu işlem başarılı olana kadar, başarısız olduğu veya iptal edildiği anlamına gelir.

getIds kullanarak tüm etkin arka plan getirmelerinin listesini alabilirsiniz:

navigator.serviceWorker.ready.then(async (swReg) => {
  const ids = await swReg.backgroundFetch.getIds();
});

Arka planda getirme kayıtları

Bir BackgroundFetchRegistration (yukarıdaki örneklerde bgFetch) aşağıdakileri içerir:

Özellikler
id string
Arka planda getirmenin kimliği.
uploadTotal number
Sunucuya gönderilecek bayt sayısı.
uploaded number
Başarıyla gönderilen bayt sayısı.
downloadTotal number
Arka planda getirme kaydedildiğinde sağlanan değer veya sıfır.
downloaded number
Başarıyla alınan bayt sayısı.

Bu değer azalabilir. Örneğin, bağlantı kesilirse ve indirme işlemi devam ettirilir. Bu durumda tarayıcı söz konusu kaynak için getirme işlemini sıfırdan yeniden başlatır.

result

Aşağıdakilerden biri:

  • "": Arka planda getirme etkin olduğundan henüz sonuç yok.
  • "success" - Arka planda getirme başarılı oldu.
  • "failure" - Arka planda getirme başarısız oldu. Bu değer yalnızca arka plan getirme işlemi, tarayıcı yeniden deneyemediğinden/devam ettiremediğinden tamamen başarısız olur.
failureReason

Aşağıdakilerden biri:

  • "" - Arka planda getirme başarısız oldu.
  • "aborted" - Arka planda getirme işlemi kullanıcı tarafından iptal edilmiştir veya abort() arandı.
  • "bad-status" - Yanıtlardan birinin durumu "tamamlanmadı" durumundaydı, ör. 404.)
  • "fetch-error" - Getirme işlemlerinden biri başka bir nedenden dolayı başarısız oldu, ör. CORS, MIX, geçersiz kısmi yanıt veya yeniden denenemez.
  • "quota-exceeded" - Arka planda depolama alanı kotasına ulaşıldı getir.
  • "download-total-exceeded" - Sağlanan "downloadTotal" değeri: aşıldı.
recordsAvailable boolean
Temel isteklere/yanıtlara erişilebilir mi?

Bu yanlışsa match ve matchAll kullanılamaz.

Yöntemler
abort() Promise<boolean> değerini döndürür.
Arka planda getirme işlemini iptal eder.

Getirme işlemi başarıyla iptal edildiyse döndürülen taahhüt true olarak çözümlenir.

matchAll(request, opts) Promise<Array<BackgroundFetchRecord>> değerini döndürür
İstekleri alın ve yanıtlar.

Buradaki bağımsız değişkenler aynıdır. önbellek API. Bağımsız değişken olmadan çağrı, tüm kayıtlar için bir söz döndürür.

Daha ayrıntılı bilgi edinmek için aşağıdaki bölümü inceleyin.

match(request, opts) Promise<BackgroundFetchRecord>
değerini döndürür, ancak şununla çözümlenir: ilk eşleşme.
Etkinlikler
progress uploaded, downloaded, result veya failureReason değişiklik.

İlerleme durumunu izleme

Bu işlem, progress etkinliği aracılığıyla yapılabilir. downloadTotal sizin için ne olursa olsun sağlanır veya bir değer girmediyseniz 0 kullanılır.

bgFetch.addEventListener('progress', () => {
  // If we didn't provide a total, we can't provide a %.
  if (!bgFetch.downloadTotal) return;

  const percent = Math.round(bgFetch.downloaded / bgFetch.downloadTotal * 100);
  console.log(`Download progress: ${percent}%`);
});

İstekleri ve yanıtları alma

bgFetch.match('/ep-5.mp3').then(async (record) => {
  if (!record) {
    console.log('No record found');
    return;
  }

  console.log(`Here's the request`, record.request);
  const response = await record.responseReady;
  console.log(`And here's the response`, response);
});

record bir BackgroundFetchRecord ve aşağıdaki gibi görünüyor:

Özellikler
request Request
Sunulan istek.
responseReady Promise<Response>
Alınan yanıt.

Yanıt, henüz alınmamış olabileceği için vaat içeriyor. Vadet getirme işlemi başarısız olursa reddedilir.

Hizmet çalışanı etkinlikleri

Etkinlikler
backgroundfetchsuccess Her şey başarıyla getirildi.
backgroundfetchfailure Getirme işlemlerinden biri veya daha fazlası başarısız oldu.
backgroundfetchabort Bir veya daha fazla getirme işlemi başarısız oldu.

Bu seçenek, yalnızca ilgili verileri temizlemeniz gerektiğinde işe yarar.

backgroundfetchclick Kullanıcı, indirme ilerleme durumu kullanıcı arayüzünü tıkladı.

Etkinlik nesneleri şunlara sahiptir:

Özellikler
registration BackgroundFetchRegistration
Yöntemler
updateUI({ title, icons }) Başlangıçta ayarladığınız başlıkları/simgeleri değiştirmenize olanak tanır. Bu isteğe bağlıdır, ancak ve gerekirse daha fazla bağlam sağlayabilirsiniz. Bu işlemi, şu süre zarfında yalnızca *bir kez* yapabilirsiniz: backgroundfetchsuccess ve backgroundfetchfailure etkinlik.

Başarıya/başarısızlığa tepki vermek

progress etkinliğini zaten gördük ancak bu yalnızca kullanıcının bir sayfası açıkken faydalı sitenizi ziyaret edin. Arka planda getirmenin temel avantajı, kullanıcı öğeden ayrıldıktan sonra da işlemlerin çalışmaya devam etmesidir. hatta tarayıcıyı kapatır.

Arka planda getirme başarıyla tamamlanırsa hizmet çalışanınız, verilerini backgroundfetchsuccess etkinliği ve event.registration arka planda getirme kaydı olacak.

Bu etkinlikten sonra, getirilen isteklere ve yanıtlara artık erişilemez. Bu nedenle, önbellek API'si gibi bir yere taşımanızı öneririz.

Çoğu Service Worker etkinliğinde olduğu gibi, Service Worker'ın etkinliğin ne zaman gerçekleştiğini bilmesi için event.waitUntil kullanın. tamamlandı.

Örneğin, hizmet çalışanınızda:

addEventListener('backgroundfetchsuccess', (event) => {
  const bgFetch = event.registration;

  event.waitUntil(async function() {
    // Create/open a cache.
    const cache = await caches.open('downloads');
    // Get all the records.
    const records = await bgFetch.matchAll();
    // Copy each request/response across.
    const promises = records.map(async (record) => {
      const response = await record.responseReady;
      await cache.put(record.request, response);
    });

    // Wait for the copying to complete.
    await Promise.all(promises);

    // Update the progress notification.
    event.updateUI({ title: 'Episode 5 ready to listen!' });
  }());
});

Hata, tek bir 404’e indirilmiş olabilir. Bu sizin için önemli olmayabilir. Dolayısıyla, yine de bazı yanıtları yukarıda belirtildiği gibi bir önbelleğe kopyalamaya değer.

Tıklamaya tepki verme

İndirme ilerlemesini ve sonucu gösteren kullanıcı arayüzü tıklanabilir. backgroundfetchclick etkinliği hizmet çalışanı buna tepki vermenize olanak tanır. Yukarıda belirtildiği gibi event.registration arka plan olacak getirme kaydını kullanın.

Bu etkinlikle ilgili genel olarak yapılan şey bir pencere açmaktır:

addEventListener('backgroundfetchclick', (event) => {
  const bgFetch = event.registration;

  if (bgFetch.result === 'success') {
    clients.openWindow('/latest-podcasts');
  } else {
    clients.openWindow('/download-progress');
  }
});

Ek kaynaklar

Düzeltme: Bu makalenin önceki bir sürümünde, Arka Planda Getirme'ye yanlışlıkla "web standardı" olarak atıfta bulunuluyor. API şu anda standartlar yolunda değil. Spesifikasyon, WICG'de Taslak Topluluk Grubu Raporu olarak bulunabilir.