Progressive Web App: Uygulama gibi davranan ve çevrim dışı (off-line) çalışabilen web sayfalarına PWA (web uygulaması) diyoruz. Bu sitenin ana sayfasını PWA haline getiren adımları burada özetliyoruz.
Web’in tarihçesini anlatan şu kitap, Resilient Web Design aynı zamanda iyi bir PWA olarak incelemeye değer.
Chrome gibi bir tarayıcı ile açarak kitabı uygulama halinde kaydedebilirsiniz. Başka bir şey indirmeye gerek yok, çevrim dışı kullabilirsiniz. Kitabın içeriği değişse bile, tekrar çevrim içi olunca sayfalar güncellenecektir.
Sayfanın Android/Chrome altında web uygulaması olması için iki adım yeterli:
(1) Ana sayfamıza iki satır ekleyelim:
<link rel="icon" href="images/JS.png">
<link rel="manifest" href="manifest.json">
Ayrıca manifest.json
dosyası şöyle olmalı:
{
"name": "JavaScript samples",
"start_url": "/JS/index.html",
"display": "standalone",
"background_color": "cyan",
"icons": [
{
"src": "images/JS.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
(2) Gerekli simgeler (bir icon yeterli)
Büyük (512x512) simge varsa, uygulama yüklenirken sistem onu kullanabilir.
favicon.io yardımı ile farklı boylarda bir simge takımı kolayca yapılabilir.
Bir web sayfası uzaktaki bir kaynağa (metin, resim, vb) erişmek istediğinde, tarayıcıya fetch talebi gönderir. Tarayıcı, ‘http GET’ mesajı ile uzaktaki kaynağı indirir ve gelen byte’ları sayfaya verir. Bu arada tarayıcının da bir ön-bellek kullandığını biliyoruz ama geliştiriciler bu belleğe erişemiyor.
Bir web uygulaması benzeri bir talep yaptığında, service worker araya girer. Cevabı ya kendi ön-belleğinde bulur ya da tarayıcıdan ister.
Masa üstünde uygulama statüsü kazanmak için, index.html içine bir service worker eklemek gerekiyor
navigator.serviceWorker.register('sw.js')
Uygulamayı çevrim dışı kullanabilmek için iki adım daha atalım:
(3) install
olayları için bir dinleyici: statik dosyaları en başta ön-belleğe alır
const CACHE ='JS'
const FILES = ['/JS/', '/JS/sss/', '/JS/index.html', ...]
function installCB(e) {
e.waitUntil(
caches.open(CACHE)
.then(cache => cache.addAll(FILES))
.catch(console.log)
)
}
self.addEventListener('install', installCB)
(4) fetch
olayları için bir dinleyici: dosyayı önce ön-bellekte arar, bulamazsa fetch talebi gönderir
function cacheCB(e) { //cache first
let req = e.request
e.respondWith(
caches.match(req)
.then(r1 => r1 || fetch(req))
.catch(console.log)
)
}
self.addEventListener('fetch', cacheCB)
Yukarıda gösterilen “önce cache” yaklaşımı, zaman içinde değişmeyen statik kaynaklar için iyi bir çözüm. Mesela, arşiv dosyaları ya da kitap bölümleri gibi. Zaman içinde değişen bir içerik söz konusu ise, daha farklı davranılır: “önce fetch”. Kaynak tarayıcıdan istenir ve gelen bilgi ön-belleğe kaydedilir. Çevrim dışı olduğu için cevap gelmezse ön-bellekteki dosya ile yetinilir.
function save(req, resp) {
return caches.open(CACHE)
.then(cache => {
cache.put(req, resp.clone());
return resp;
})
.catch(console.log)
}
function fetchCB(e) { //fetch first
let req = e.request
e.respondWith(
fetch(req).then(r2 => save(req, r2))
.catch(() => { return caches.match(req).then(r1 => r1) })
)
}
self.addEventListener('fetch', fetchCB)
index.html
(değişecek)manifest.json
(PWA bilgisi)images/JS.png
(icon)sw.js
(service worker)