Bu codelab'de, Workbox ile nasıl esnek bir arama deneyimi uygulayabileceğiniz gösterilmektedir. Kullandığı demo uygulaması, sunucu uç noktasına çağrı yapan ve kullanıcıyı temel bir HTML sayfasına yönlendiren bir arama kutusu içerir.
Ölçüm
Optimizasyon eklemeden önce, uygulamanın mevcut durumunu analiz etmek her zaman iyi bir fikirdir.
- Projeyi düzenlenebilir hale getirmek için Düzenlemek için remiks oluştur'u tıklayın.
- Siteyi önizlemek için Uygulamayı Görüntüle'ye, ardından Tam Ekran'a basın.
Açılan yeni sekmede, web sitesinin çevrimdışıyken nasıl davrandığını kontrol edin:
- Geliştirici Araçları'nı açmak için "Kontrol+Üst Karakter+J" (veya Mac'te "Komut+Option+J") tuşlarına basın.
- Ağ sekmesini tıklayın.
- Chrome Geliştirici Araçları'nı açıp Ağ panelini seçin.
- Kısıtlama açılır listesinde Çevrimdışı'nı seçin.
- Demo uygulamasında bir arama sorgusu girip Ara düğmesini tıklayın.
Standart tarayıcı hata sayfası gösterilir:
Yedek yanıt sağlama
Hizmet çalışanı, çevrimdışı sayfayı ön önbelleğe alma listesine ekleme kodunu içerir. Bu sayede, sayfa her zaman hizmet çalışanı install
etkinliğinde önbelleğe alınabilir.
Genellikle, kitaplığı tercih ettiğiniz derleme aracıyla (ör. webpack veya gulp) entegre ederek Workbox'a bu dosyayı derleme sırasında ön önbelleğe alma listesine eklemesini talimatlamanız gerekir.
Basitleştirmek için bu işlemi sizin için zaten yaptık. public/sw.js
adresindeki aşağıdaki kod bunu yapar:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Ardından, çevrimdışı sayfayı yedek yanıt olarak kullanmak için kod ekleyin:
- Kaynağı görüntülemek için Kaynağı Görüntüle'ye basın.
public/sw.js
öğesinin altına şu kodu ekleyin:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
Kod şu işlemleri yapar:
- Tüm istekler için geçerli olacak varsayılan bir Yalnızca Ağ stratejisi tanımlar.
- Başarısız istekleri yönetmek için
workbox.routing.setCatchHandler()
çağrısı yaparak global bir hata işleyici tanımlar. İstekler dokümanlar için olduğunda yedek çevrimdışı HTML sayfası döndürülür.
Bu işlevi test etmek için:
- Uygulamanızı çalıştıran diğer sekmeye geri dönün.
- Düşük hız açılır listesini tekrar Online olarak ayarlayın.
- Arama sayfasına geri gitmek için Chrome'un Geri düğmesine basın.
- Geliştirici Araçları'ndaki Önbelleği devre dışı bırak onay kutusunun devre dışı olduğundan emin olun.
- Hizmet çalışanınızın güncellendiğinden emin olmak için Chrome'un Yeniden yükle düğmesine uzun basın ve Önbelleği boşalt ve yeniden yükle'yi seçin.
- Throttling açılır listesini tekrar Çevrimdışı olarak ayarlayın.
- Bir arama sorgusu girip Ara düğmesini tekrar tıklayın.
Yedek HTML sayfası gösterilir:
Bildirim izni isteme
Basitlik sağlamak amacıyla, views/index_offline.html
adresindeki çevrimdışı sayfada, alt kısımdaki bir komut dosyası bloğunda bildirim izinleri isteğinde bulunma kodu zaten mevcuttur:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Kod şunları yapar:
- Kullanıcı Bildirimlere abone ol'u tıkladığında
requestNotificationPermission()
işlevi çağrılır. Bu işlev, varsayılan tarayıcı izni istemlerini göstermek içinNotification.requestPermission()
işlevini çağırır. Söz, kullanıcı tarafından seçilen izinle çözülür. Bu izingranted
,denied
veyadefault
olabilir. - Çözüme ulaştırılan izni, kullanıcıya uygun metni göstermek için
showOfflineText()
öğesine iletir.
Çevrimdışı sorguları sürdürme ve internete tekrar bağlandığınızda yeniden deneme
Ardından, çevrimdışı sorguları devam ettirmek için Workbox Arka Plan Senkronizasyonu'nu uygulayın. Böylece tarayıcı, bağlantının geri geldiğini algıladığında sorguların yeniden denenmesi sağlanır.
- Düzenlemek için
public/sw.js
dosyasını açın. - Dosyanın sonuna aşağıdaki kodu ekleyin:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
Kod şu işlemleri yapar:
workbox.backgroundSync.Plugin
, başarısız isteklerin daha sonra yeniden denenebilmesi için bir kuyruğa eklenme mantığını içerir. Bu istekler IndexedDB'de kalır.maxRetentionTime
, bir isteğin yeniden denemeye uygun olduğu süreyi belirtir. Bu durumda 60 dakikayı seçtik (bu sürenin ardından veriler silinir).onSync
, bu kodun en önemli kısmıdır. Bu geri çağırma işlevi, bağlantı tekrar kurulduktan sonra çağrılır. Böylece, sıraya alınmış istekler alınır ve ağdan getirilir.- Ağ yanıtı,
¬ification=true
sorgu parametresi eklenerekoffline-search-responses
önbelleğine eklenir. Böylece, kullanıcı bildirimi tıkladığında bu önbellek girişi alınabilir.
Arka plan senkronizasyonunu hizmetinizle entegre etmek için arama URL'sine (/search_action
) yapılan istekler için NetworkOnly stratejisi tanımlayın ve daha önce tanımlanmış bgSyncPlugin
değerini iletin. public/sw.js
dosyasının altına aşağıdaki kodu ekleyin:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
Bu, Workbox'a her zaman ağa gitmesini ve istekler başarısız olduğunda arka plan senkronizasyon mantığını kullanmasını söyler.
Ardından, bildirimlerden gelen istekler için bir önbelleğe alma stratejisi tanımlamak üzere public/sw.js
'ün alt kısmına aşağıdaki kodu ekleyin. Bu öğelerin önbellekten sunulabilmesi için CacheFirst stratejisini kullanın.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
Son olarak, bildirimleri göstermek için kodu ekleyin:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
Özelliği test etme
- Uygulamanızı çalıştıran diğer sekmeye geri dönün.
- Düşük hız açılır listesini tekrar Online olarak ayarlayın.
- Arama sayfasına geri gitmek için Chrome'un Geri düğmesine basın.
- Hizmet çalışanınızın güncellendiğinden emin olmak için Chrome'un Yeniden yükle düğmesine uzun basın ve Önbelleği boşalt ve yeniden yükle'yi seçin.
- Düşürme açılır listesini tekrar Çevrimdışı olarak ayarlayın.
- Bir arama sorgusu girip Ara düğmesini tekrar tıklayın.
- Bildirimlere abone ol'u tıklayın.
- Chrome, uygulamanın bildirim göndermesine izin vermek isteyip istemediğinizi sorduğunda İzin ver'i tıklayın.
- Başka bir arama sorgusu girin ve Ara düğmesini tekrar tıklayın.
- Throttling açılır listesini tekrar Online olarak ayarlayın.
Bağlantı tekrar kurulduğunda bir bildirim gösterilir:
Sonuç
Workbox, PWA'larınızı daha dayanıklı ve ilgi çekici hale getirmek için birçok yerleşik özellik sunar. Bu kod laboratuvarında, çevrimdışı kullanıcı sorgularının kaybolmamasını ve bağlantı tekrar kurulduktan sonra yeniden denenebilmesini sağlamak için Workbox soyutlaması aracılığıyla Arka Plan Senkronizasyonu API'sinin nasıl uygulanacağını incelediniz. Demo basit bir arama uygulamasıdır ancak sohbet uygulamaları, sosyal ağda mesaj yayınlama vb. gibi daha karmaşık senaryolar ve kullanım alanları için benzer bir uygulama kullanabilirsiniz.