2015'te, hizmet çalışanının kullanıcının bağlantısı olana kadar işi ertelemelerine olanak tanıyan Arka Plan Senkronizasyonu'nu kullanıma sunduk. Bu sayede kullanıcı bir mesaj yazıp gönder düğmesine basabilir ve mesajın hemen veya bağlantısı olduğunda gönderileceğini bilerek siteden ayrılabilir.
Bu kullanışlı bir özelliktir ancak getirme işlemi sırasında hizmet çalışanının etkin olması gerekir. Bu, mesaj gönderme gibi kısa işlemler için sorun oluşturmaz ancak görev çok uzun sürerse tarayıcı hizmet çalışanını sonlandırır. Aksi takdirde, kullanıcının gizliliği ve pili için risk oluşur.
Peki film, podcast veya oyun seviyeleri gibi uzun süren bir indirme işleminiz varsa ne yapabilirsiniz? Arka planda getirme bu sorunu çözmek için tasarlanmıştır.
Arka Planda Getirme, Chrome 74'ten itibaren varsayılan olarak kullanılabilir.
Aşağıda, arka planda getirme özelliğinin kullanılmadığı ve kullanıldığı durumları gösteren iki dakikalık kısa bir demo verilmiştir:
Demoyu kendiniz deneyin ve koda göz atın.
İşleyiş şekli
Arka planda getirme işlemi şu şekilde işler:
- Tarayıcıya arka planda bir grup getirme işlemi gerçekleştirmesini söylersiniz.
- Tarayıcı bu öğeleri getirir ve kullanıcıya ilerleme durumunu gösterir.
- Getirme işlemi tamamlandığında veya başarısız olduğunda tarayıcı, servis çalışanınızı açar ve ne olduğunu size bildirmek için bir etkinlik tetikler. Yanıtlarla (varsa) ne yapacağınıza burada karar verirsiniz.
Kullanıcı 1. adımdan sonra sitenizin sayfalarını kapatırsa indirme işlemi devam eder. Getirme işlemi çok görünür olduğundan ve kolayca iptal edilebildiğinden, çok uzun süren arka plan senkronizasyonu görevi nedeniyle gizlilikle ilgili endişeler yaşanmaz. Hizmet çalışanı sürekli çalışmadığından, arka planda bitcoin madenciliği yapmak gibi sistemi kötüye kullanabileceği konusunda endişelenmenize gerek yoktur.
Bazı platformlarda (ör. Android), tarayıcı getirme işlemini işletim sistemine devredebileceğinden 1. adımdan sonra kapanabilir.
Kullanıcı indirme işlemini çevrimdışıyken başlatırsa veya indirme sırasında çevrimdışı olursa arka planda getirme duraklatılır ve daha sonra devam ettirilir.
API
Özellik algılama
Her yeni özellikte olduğu gibi, tarayıcının bu özelliği destekleyip desteklemediğini algılamak istersiniz. Arka planda getirme için yapmanız gerekenler:
if ('BackgroundFetchManager' in self) {
// This browser supports Background Fetch!
}
Arka planda getirme işlemini başlatma
Ana API, bir Service Worker kaydına bağlıdır. Bu nedenle, önce bir Service Worker 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 plan getirme işlemiyle eşleşirse |
requests |
Array<Request|string>
Getirilecek öğeler. Dizeler URL olarak değerlendirilir ve new Request(theString) aracılığıyla Request olarak dönüştürülür.
Kaynaklar izin verdiği sürece CORS aracılığıyla diğer kaynaklardan öğe getirebilirsiniz. Not: Chrome şu anda CORS ön uçuş gerektiren istekleri desteklememektedir. |
options |
Aşağıdakileri içerebilen bir nesne: |
options.title |
string Tarayıcının ilerleme durumunu göstereceği başlık. |
options.icons |
Array<IconDefinition> "src", "size" ve "type" değerlerine sahip bir nesne dizisi. |
options.downloadTotal |
number Yanıt gövdelerinin toplam boyutu (sıkıştırma kaldırıldıktan sonra). Bu isteğe bağlıdır ancak sağlamanız önemle tavsiye edilir. Kullanıcıya indirme işleminin ne kadar büyük olduğunu bildirmek ve ilerleme durumu bilgisi sağlamak için kullanılır. Bu bilgiyi sağlamazsanız tarayıcı, kullanıcıya boyutun bilinmediğini söyler. Bu durumda kullanıcının indirme işlemini iptal etme olasılığı artar. Arka planda getirme işlemi, burada belirtilen sayıyı aşarsa iptal edilir. İndirme işlemi |
backgroundFetch.fetch
, BackgroundFetchRegistration
ile çözülen bir promise döndürür. Ayrıntıları daha sonra ele alacağız. Kullanıcı indirmeleri devre dışı bıraktıysa veya sağlanan parametrelerden biri geçersizse söz verme işlemi reddedilir.
Tek bir arka plan getirme işlemi için birçok istek göndermek, kullanıcı için mantıksal olarak tek bir şey olan öğeleri birleştirmenize olanak tanır. Örneğin, bir film 1.000'lerce kaynağa bölünebilir (MPEG-DASH ile yaygındır) ve resimler gibi ek kaynaklar içerebilir. Bir oyunun seviyesi birçok JavaScript, resim ve ses kaynağına yayılabilir. Ancak kullanıcı için bu "film" veya "seviye"dir.
Mevcut bir arka planda getirme işlemini alma
Mevcut bir arka plan getirme işlemini şu şekilde alabilirsiniz:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
İstediğiniz arka plan getirme işleminin kimliğini ileterek Söz konusu kimlikle etkin bir arka plan getirme işlemi yoksa get
undefined
değerini döndürür.
Arka planda getirme işlemi, kaydedildiği andan itibaren başarılı olana, başarısız olana veya iptal edilene kadar "etkin" olarak kabul edilir.
getIds
kullanarak tüm etkin arka plan getirme işlemlerinin listesini alabilirsiniz:
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
Arka planda getirme kayıtları
BackgroundFetchRegistration
(yukarıdaki örneklerde bgFetch
), aşağıdakileri içerir:
Özellikler | |
---|---|
id |
string Arka planda getirme işleminin kimliği. |
uploadTotal |
number Sunacuya gönderilecek bayt sayısı. |
uploaded |
number Başarıyla gönderilen bayt sayısı. |
downloadTotal |
number Arka planda getirme işlemi kaydedilirken sağlanan değer veya sıfır. |
downloaded |
number Başarıyla alınan bayt sayısı. Bu değer düşebilir. Örneğin, bağlantı kesilirse ve indirme işlemi devam ettirilemezse tarayıcı, söz konusu kaynağın getirilmesini sıfırdan başlatır. |
result |
Aşağıdakilerden biri:
|
failureReason |
Aşağıdakilerden biri:
|
recordsAvailable |
boolean Temel isteklere/yanıtlara erişilebilir mi? Bu değer yanlış olduğunda |
Yöntemler | |
abort() |
Promise<boolean> döndürür. Arka planda getirme işlemini iptal eder. Getirme işlemi başarıyla iptal edildiyse döndürülen promise true ile çözülür. |
matchAll(request, opts) |
Döndürülen değer Promise<Array<BackgroundFetchRecord>> İstekleri ve yanıtları alın. Buradaki bağımsız değişkenler, önbellek API'siyle aynıdır. Bağımsız değişken olmadan çağrıldığında tüm kayıtlar için bir promise döndürülür. Daha ayrıntılı bilgi edinmek için aşağıdaki bölümü inceleyin. |
match(request, opts) |
Promise<BackgroundFetchRecord> döndürürYukarıdaki gibidir ancak ilk eşleşmeyle çözünür. |
Etkinlikler | |
progress |
uploaded , downloaded , result veya failureReason değiştiğinde tetiklenir. |
İlerleme durumunu izleme
Bu işlem, progress
etkinliği aracılığıyla yapılabilir. downloadTotal
değerinin, belirttiğiniz değeri veya değer belirtmediyseniz 0
değerini ifade ettiğini unutmayın.
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
'dir ve şu şekilde görünür:
Özellikler | |
---|---|
request |
Request Sağlanan istek. |
responseReady |
Promise<Response> Getirilen yanıt. Yanıt henüz alınmamış olabileceği için söz verilen sürede gönderilmemiştir. Getirme işlemi başarısız olursa söz |
Hizmet çalışanı etkinlikleri
Etkinlikler | |
---|---|
backgroundfetchsuccess |
Tüm veriler 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 işlem, yalnızca ilgili verileri temizlemek istiyorsanız faydalıdır. |
backgroundfetchclick |
Kullanıcı, indirme ilerleme durumunu gösteren kullanıcı arayüzünü tıkladı. |
Etkinlik nesneleri şunları içerir:
Özellikler | |
---|---|
registration |
BackgroundFetchRegistration |
Yöntemler | |
updateUI({ title, icons }) |
İlk olarak ayarladığınız başlığı/simgeleri değiştirmenize olanak tanır. Bu isteğe bağlıdır ancak gerekirse daha fazla bağlam bilgisi eklemenize olanak tanır. Bu işlemi backgroundfetchsuccess ve backgroundfetchfailure etkinlikleri sırasında yalnızca *bir kez* yapabilirsiniz. |
Başarıya/başarısızlığa tepki verme
progress
etkinliğini daha önce görmüştük ancak bu etkinlik yalnızca kullanıcının sitenizde açık bir sayfası olduğunda faydalıdır. Arka planda getirmenin en büyük avantajı, kullanıcı sayfadan ayrıldıktan veya hatta tarayıcıyı kapattıktan sonra işlemlerin çalışmaya devam etmesidir.
Arka planda getirme işlemi başarıyla tamamlanırsa servis çalışanınız backgroundfetchsuccess
etkinliğini alır ve event.registration
, arka planda getirme kaydı olur.
Bu olaydan sonra getirilen istek ve yanıtlara artık erişilemez. Bu nedenle, saklamak istediğiniz istek ve yanıtları önbellek API'si gibi bir yere taşıyın.
Çoğu hizmet çalışanı etkinliğinde olduğu gibi, hizmet çalışanının etkinliğin ne zaman tamamlandığını bilmesi için event.waitUntil
değerini kullanın.
Örneğin, servis ç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!' });
}());
});
Başarısızlık, sizin için önemli olmayabilecek tek bir 404 hatasından kaynaklanmış olabilir. Bu nedenle, bazı yanıtları yukarıdaki gibi bir önbelleğe kopyalamak yine de faydalı olabilir.
Tıklamalara tepki verme
İndirme işleminin ilerleme durumunu ve sonucunu gösteren kullanıcı arayüzü tıklanabilir. Hizmet çalışanındaki backgroundfetchclick
etkinliği, buna tepki vermenize olanak tanır. Yukarıda belirtildiği gibi event.registration
, kayıtları arka planda getirme işlemidir.
Bu olayla ilgili olarak genellikle bir pencere açılı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 özelliği "web standardı" olarak yanlış bir şekilde belirtilmişti. API şu anda standartlar kapsamında değil. Şartname, WICG'de taslak topluluk grubu raporu olarak bulunabilir.