ãã®è¨äºã¯ãµã¼ãã¹ã¯ã¼ã«ã¼ã使ãå§ããããã®æ å ±ãæä¾ãããã¼ã¸ã§ããåºæ¬çãªæ§é ããµã¼ãã¹ã¯ã¼ã«ã¼ã®ç»é²ãæ°ãããµã¼ãã¹ã¯ã¼ã«ã¼ã®ã¤ã³ã¹ãã¼ã«ã¨æå¹åã®ããã»ã¹ããµã¼ãã¹ã¯ã¼ã«ã¼ã®æ´æ°ããã£ãã·ã¥ãã¬ã¹ãã³ã¹ã®æä½ãå«ããããªãã©ã¤ã³ã§åä½ããã·ã³ãã«ãªã¢ããªã±ã¼ã·ã§ã³ã®æ©è½ã«ã¤ãã¦ã§ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã®åææ¡ä»¶ã¦ã§ãã¦ã¼ã¶ã¼ãé·å¹´è¦ããããã¦ãã主è¦ãªåé¡ã®ä¸ã¤ã¯ãæ¥ç¶ã失ããã¨ã§ããä¸çä¸ã®æé«ã®ã¦ã§ãã¢ããªã¯ããã¦ã³ãã¼ãã§ããªãã¨ãã®ä½¿ãåæãææªã§ãããããã¾ã§ã«ãããã®åé¡ã解決ããããã®æè¡ãçã¿åºã試ã¿ã¯ãã¾ãã¾ã«è¡ãããããã¤ãã®åé¡ã¯è§£æ±ºããã¦ãã¾ãããããããä¸çªã®åé¡ã¯ãè³ç£ã®ãã£ãã·ã¥ã¨ã«ã¹ã¿ã ãããã¯ã¼ã¯ãªã¯ã¨ã¹ãã®ããã®åªããå ¨ä½çãªå¶å¾¡ã¡ã«ããºã ãåå¨ããªãã£ããã¨ã§ãã
ãã®ãããªèª²é¡ãä¿®æ£ããã®ããµã¼ãã¹ã¯ã¼ã«ã¼ã§ãããµã¼ãã¹ã¯ã¼ã«ã¼ã使ç¨ããã¨ããã£ãã·ã¥è³ç£ãæåã«ä½¿ç¨ããããã«ã¢ããªãè¨å®ãããã¨ãã§ãããããã£ã¦ãããã¯ã¼ã¯ããããå¤ãã®ãã¼ã¿ãåå¾ããåã«ããªãã©ã¤ã³ã®å ´åã§ãæ¢å®ã®ä½¿ãåæãæä¾ãããã¨ãã§ãã¾ãï¼ä¸è¬ã«ããªãã©ã¤ã³ãã¡ã¼ã¹ããã¨å¼ã°ãã¾ãï¼ãããã¯ãã¤ãã£ãã¢ããªã§ãã§ã«å©ç¨ã§ãããã¨ã§ãã¦ã§ãã¢ããªããããã¤ãã£ãã¢ããªãå¤ãé¸ã°ãã主ãªçç±ã®ã²ã¨ã¤ã§ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã¯ãããã·ã¼ãµã¼ãã¼ã®ããã«æ©è½ãããªã¯ã¨ã¹ããã¬ã¹ãã³ã¹ãèªåèªèº«ã§ãã£ãã·ã¥ã«ç½®ãæãã¦å¤æ´ãããã¨ãã§ãã¾ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ãå®è¡ããããã®è¨å®ãµã¼ãã¹ã¯ã¼ã«ã¼ã¯ãç¾ä»£ã®ãã¹ã¦ã®ãã©ã¦ã¶ã¼ã§ãæ¢å®ã§æå¹ã«ãªã£ã¦ãã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ã使ç¨ãã¦ã³ã¼ããå®è¡ããã«ã¯ãã³ã¼ãã HTTPS ã§æä¾ããå¿
è¦ãããã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ãã»ãã¥ãªãã£ä¸ã®çç±ãã HTTPS ãä»ãã¦å®è¡ããããã«å¶éããã¦ãã¾ããHTTPS ã«å¯¾å¿ãã¦ãããµã¼ãã¼ãå¿
è¦ã§ããå®é¨ããã¹ãã£ã³ã°ããã«ã¯ãGitHubãNetlifyãVercel ãªã©ã®ãµã¼ãã¹ã使ç¨ãããã¨ãã§ãã¾ãããã¼ã«ã«éçºã容æã«ããããã«ãlocalhost
ã¯ãã©ã¦ã¶ã¼ã§ãå®å
¨ãªãªãªã¸ã³ã¨ã¿ãªããã¾ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã§ã¯ãåºæ¬çãªã»ããã¢ããã®éã«ä¸è¨ã®ã¹ããããä¸è¬çã«è¦ããã¾ãã
serviceWorkerContainer.register()
ãéãã¦ç»é²ããã¾ããæåããå ´åããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ ServiceWorkerGlobalScope
ã§å®è¡ããã¾ããããã¯æ ¹æ¬çã«ç¹æ®ãªã¯ã¼ã«ã¼ã³ã³ããã¹ãã§ãã¡ã¤ã³ã¹ã¬ããããç¬ç«ãã¦ããã DOM ã¸ã®ã¢ã¯ã»ã¹ãããã¾ãããinstall
ã¤ãã³ãã¯å¸¸ã«ãµã¼ãã¹ã¯ã¼ã«ã¼ã«éãããæåã®ã¤ãã³ãã§ãï¼ããã使ç¨ã㦠IndexedDB ãè¨å®ãããããµã¤ãè³ç£ããã£ãã·ã¥ãããããããã»ã¹ãéå§ãããã¨ãã§ãã¾ãï¼ããã®æ®µéã§ã¯ãã¢ããªã±ã¼ã·ã§ã³ã¯ãªãã©ã¤ã³ã§ä½¿ç¨ããããã®ãã¹ã¦ã®æºåããã¾ããinstall
ãã³ãã©ã¼ãå®äºããã¨ããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ã¤ã³ã¹ãã¼ã«ãããã¨è¦ãªããã¾ãããã®æç¹ã§ãååã¾ã§ã®ãã¼ã¸ã§ã³ã®ãµã¼ãã¹ã¯ã¼ã«ã¼ãã¢ã¯ãã£ãã«ãªã£ã¦ããããã¼ã¸ãéãããã®å¶å¾¡ããã¦ããå¯è½æ§ãããã¾ããåããµã¼ãã¹ã¯ã¼ã«ã¼ã®ç°ãªã2ã¤ã®ãã¼ã¸ã§ã³ãåæã«å®è¡ãããã¨ã¯é¿ãããã®ã§ãæ°ãããã¼ã¸ã§ã³ã¯ã¾ã ã¢ã¯ãã£ãã«ã¯ãªãã¾ãããactivate
ã¤ãã³ããåãåãã¾ããactivate
ã®ä¸»ãªä½¿ç¨ç®çã¯ã以åã®ãã¼ã¸ã§ã³ã®ãµã¼ãã¹ã¯ã¼ã«ã¼ã§ä½¿ç¨ãã¦ãããªã½ã¼ã¹ãã¯ãªã¼ã³ã¢ãããããã¨ã§ããæ°ãããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ skipWaiting()
ãå¼ã³åºããã¨ã§ãéãã¦ãããã¼ã¸ãéããããã®ãå¾
ããã«ããã«ã¢ã¯ãã£ãåãããã¨ããªã¯ã¨ã¹ããããã¨ãã§ãã¾ããæ°ãããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ç´ã¡ã« activate
ãåãåããéãã¦ãããã¼ã¸ãå¼ãç¶ãã¾ããregister()
ãæåããå¾ã«éããããã¼ã¸ã ãã§ããè¨ãæããã°ãææ¸ãå®éã«å¶å¾¡ä¸ã«å
¥ãã«ã¯ãåèªã¿è¾¼ã¿ãå¿
è¦ã§ããããã¯ãææ¸ã«ããããµã¼ãã¹ã¯ã¼ã«ã¼ã®æç¡ã¯ã©ã¤ããµã¤ã¯ã«ã®éå§æã«æ±ºã¾ããçµäºæã¾ã§ãã®ç¶æ
ãç¶æãããããã§ãããµã¼ãã¹ã¯ã¼ã«ã¼ã clients.claim()
ãå¼ã³åºãã¨ããã®æ¢å®ã®åä½ã䏿¸ããã¦ãéãã¦ãããã¼ã¸ã«é¢ä¸ãããã¨ãã§ãã¾ããå©ç¨å¯è½ãªãµã¼ãã¹ã¯ã¼ã«ã¼ã®ã¤ãã³ãã®æ¦è¦ã¯æ¬¡ã®éãã§ãã
ãã¢ãµã¼ãã¹ã¯ã¼ã«ã¼ã®ç»é²ã¨ã¤ã³ã¹ãã¼ã«ã®ããåºæ¬çãªãã¨ã示ãããã«ãã·ã³ãã«ãªãµã¼ãã¹ã¯ã¼ã«ã¼ ã¨ããã·ã³ãã«ãªãã¢ã使ãã¾ãããããã¯ãã·ã³ãã«ãª Star Wars ã¬ã´ã®ç»åã®ã£ã©ãªã¼ã§ããããã¯ããããã¹ãå©ç¨ãã颿°ã§ã JSON ãªãã¸ã§ã¯ãããç»åãã¼ã¿ãèªã¿è¾¼ã¿ã fetch()
ãç¨ãã¦ç»åãèªã¿è¾¼ãã§ããããã¼ã¸ã®ä¸ã«ç»åã並ã¹ã¦è¡¨ç¤ºãããã®ã§ããä»ã®ã¨ããéçã§ã·ã³ãã«ãªãã®ã«ãã¦ãã¾ããã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ãç»é²ãã¤ã³ã¹ãã¼ã«ãã¢ã¯ãã£ãåãã¦ãã¾ãã
GitHub ä¸ã®ã½ã¼ã¹ã³ã¼ãã確èªããä¾ãã©ã¤ãã§è¡¨ç¤ºãã¦ã¿ã¾ãããã
ã¯ã¼ã«ã¼ã®ç»é²ãã®ã¢ããªã® JavaScript ãã¡ã¤ã«ã§ãã app.js
ã®æåã®ã³ã¼ããããã¯ã¯ã以ä¸ã®éãã§ããããã¯ããµã¼ãã¹ã¯ã¼ã«ã¼ã使ç¨ããããã®ã¨ã³ããªã¼ãã¤ã³ãã§ãã
const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) {
try {
const registration = await navigator.serviceWorker.register("/sw.js", {
scope: "/",
});
if (registration.installing) {
console.log("Service worker installing");
} else if (registration.waiting) {
console.log("Service worker installed");
} else if (registration.active) {
console.log("Service worker active");
}
} catch (error) {
console.error(`Registration failed with ${error}`);
}
}
};
// â¦
registerServiceWorker();
if
ãããã¯ã¯ãç»é²ã試ã¿ãåã«ãµã¼ãã¹ã¯ã¼ã«ã¼ã«å¯¾å¿ãã¦ããã確èªããæ©è½æ¤åºè©¦é¨ãè¡ãã¾ããServiceWorkerContainer.register()
颿°ã使ã£ã¦ããã®ãµã¤ãã®ãµã¼ãã¹ã¯ã¼ã«ã¼ãç»é²ãã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ã®ã³ã¼ãã¯ã¢ããªå
ã«ããã¾ãï¼ãªããããã¯ãªãªã¸ã³ããã®ãã¡ã¤ã«ã®ç¸å¯¾ URL ã§ãã£ã¦ããããåç
§ãã¦ãã JS ãã¡ã¤ã«ã§ã¯ããã¾ããï¼ãscope
弿°ã¯ãªãã·ã§ã³ã§ããµã¼ãã¹ã¯ã¼ã«ã¼ãå¶å¾¡ããã³ã³ãã³ãã®ãµãã»ãããæå®ãããã¨ãã§ãã¾ãããã®ã±ã¼ã¹ã§ã¯ '/'
ãæå®ãã¦ãããã¢ããªã®ãªãªã¸ã³é
ä¸ã®ãã¹ã¦ã®ã³ã³ãã³ããæå³ãã¦ãã¾ãããããããæå®ããªãã¦ããã®å¤ãæ¢å®å¤ã«ãªãã¾ãããæå®æ¹æ³ã示ãããã«ä½¿ç¨ãã¦ãã¾ããããã¯ãã¯ã¼ã«ã¼ã®ã³ã³ããã¹ãã§å®è¡ããããµã¼ãã¹ã¯ã¼ã«ã¼ãç»é²ãã¦ããããã DOM ã«ã¯ã¢ã¯ã»ã¹ãã¦ãã¾ããã
1 ã¤ã®ãµã¼ãã¹ã¯ã¼ã«ã¼ã§ã夿°ã®ãã¼ã¸ãå¶å¾¡ãããã¨ãã§ãã¾ããã¹ã³ã¼ãå ã®ãã¼ã¸ãèªã¿è¾¼ã¾ãããã³ã«ããµã¼ãã¹ã¯ã¼ã«ã¼ã¯ãã®ãã¼ã¸ã«ã¤ã³ã¹ãã¼ã«ããã¦åä½ãã¾ãããã®ããããµã¼ãã¹ã¯ã¼ã«ã¼ã¹ã¯ãªããå ã§ã®ã°ãã¼ãã«å¤æ°ã®æ±ãã«ã¯æ³¨æãå¿ è¦ã ã¨ãããã¨ãå¿ã«ã¨ã©ãã¦ããã¦ãã ãããåãã¼ã¸ãåºæã®ã¯ã¼ã«ã¼ãæã¤ããã§ã¯ããã¾ããã
ã¡ã¢: ãµã¼ãã¹ã¯ã¼ã«ã¼ã®è¯ãã¨ããã¯ã以ä¸ã§è¦ã¦ãããããªæ©è½ã®æ¤åºããããã¨ã§ããµã¼ãã¹ã¯ã¼ã«ã¼ã«å¯¾å¿ãã¦ããªããã©ã¦ã¶ã¼ã§ããªã³ã©ã¤ã³ã§æå¾ éãã®æµåã§ã¢ããªã使ç¨ãããã¨ãã§ãããã¨ã§ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã®ç»é²ã«å¤±æããçç±æ¬¡ã®å¯è½æ§ãèãããã¾ãã
https://bncb2v.csb.app/sw.js
ã«ãããã¢ããªã®ã«ã¼ã㯠https://bncb2v.csb.app/
ã§ãããããããã¹ã¯ /sw.js
ã¨æ¸ãå¿
è¦ãããã¾ããsw.js
ã /js/sw.js
ã«ããå ´åã æ¢å®ã§ã¯ /js/
以ä¸ã® URL ããå¶å¾¡ã§ãã¾ããï¼ããµã¼ãã¹ã¯ã¼ã«ã¼ã®æå¤§ã¹ã³ã¼ãã®ãªã¹ã㯠Service-Worker-Allowed
ãããã¼ã§æå®ãããã¨ãã§ãã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ãç»é²ããå¾ããã©ã¦ã¶ã¼ã¯ãã¼ã¸/ãµã¤ãä¸ã§ãµã¼ãã¹ã¯ã¼ã«ã¼ãã¤ã³ã¹ãã¼ã«ããã³ã¢ã¯ãã£ãåãããã¨ãã¾ãã
ã¤ã³ã¹ãã¼ã«ãæå裡ã«å®äºããã¨ãã install
ã¤ãã³ããçºè¡ããã¾ããé常ã install
ã¤ãã³ãã¯ãªãã©ã¤ã³ã§å®è¡ããå¿
è¦ã®ããè³ç£ãããã©ã¦ã¶ã¼ã®ãªãã©ã¤ã³ãã£ãã·ã¥é åã«é
ç½®ããããã«ä½¿ããã¾ãããããããããã«ããµã¼ãã¹ã¯ã¼ã«ã¼ã®ã¹ãã¬ã¼ã¸ API â cache
â ã使ç¨ãã¾ãããã£ãã·ã¥ã¯ãµã¼ãã¹ã¯ã¼ã«ã¼ã®ã°ãã¼ãã«ãªãã¸ã§ã¯ãã§ãã¬ã¹ãã³ã¹ã«ãã£ã¦é
ä¿¡ãããè³ç£ãããã®ãªã¯ã¨ã¹ãããã¼ã«ãã¦ä¿åãããã¨ãã§ãã¾ãããã® API ã¯ãã©ã¦ã¶ã¼ã®æ¨æºãã£ãã·ã¥ã¨åãããã«åä½ãã¾ããããã®ãã¡ã¤ã³ã«ç¹åãã¦ãã¾ãããã£ãã·ã¥ã®ã³ã³ãã³ãã¯ãã¯ãªã¢ããã¾ã§ä¿æããã¾ãã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã install
ã¤ãã³ããæ±ãæ¹æ³ã®ä¾ã§ãã
const addResourcesToCache = async (resources) => {
const cache = await caches.open("v1");
await cache.addAll(resources);
};
self.addEventListener("install", (event) => {
event.waitUntil(
addResourcesToCache([
"/",
"/index.html",
"/style.css",
"/app.js",
"/image-list.js",
"/star-wars-logo.jpg",
"/gallery/bountyHunters.jpg",
"/gallery/myLittleVader.jpg",
"/gallery/snowTroopers.jpg",
]),
);
});
ExtendableEvent.waitUntil()
ã¡ã½ããããã§ã¼ã³ãã¦ãã¾ã â ãã㯠waitUntil()
ã®å
é¨ã®ã³ã¼ããæå裡ã«å®è¡ãããã¾ã§ããµã¼ãã¹ã¯ã¼ã«ã¼ãã¤ã³ã¹ãã¼ã«ãããªããã¨ãä¿è¨¼ãã¾ããaddResourcesToCache()
ã®å
é¨ã§ã caches.open()
ã使ç¨ãã¦ã v1
ã¨å¼ã°ããæ°ãããã£ãã·ã¥ã使ãã¾ããããã¯ãµã¤ããªã½ã¼ã¹ãã£ãã·ã¥ã®ãã¼ã¸ã§ã³ 1 ã¨ãªãã¾ããæ¬¡ã«ã使ããããã£ãã·ã¥ã«å¯¾ã㦠addAll()
ãå¼ã³åºã颿°ãå¼ã³åºãã¾ãããã®é¢æ°ã®å¼æ°ã«ã¯ããã£ãã·ã¥ããããã¹ã¦ã®ãªã½ã¼ã¹ã®ãªãªã¸ã³ããã®ç¸å¯¾ URL ã®é
åãæ¸¡ããã¾ããURL ã¯ã¯ã¼ã«ã¼ã® location ããã®ç¸å¯¾ãã¹ã§ããã¡ã¢: ã¦ã§ãã¹ãã¬ã¼ã¸ API (localStorage
) ã¯ãµã¼ãã¹ã¯ã¼ã«ã¼ãã£ãã·ã¥ã¨åãããã«åä½ãã¾ãããåæå¦çã§ããããããµã¼ãã¹ã¯ã¼ã«ã¼å
ã§ã¯è¨±å¯ããã¦ãã¾ããã
ã¡ã¢: å¿ è¦ã§ããã°ã IndexedDB ããµã¼ãã¹ã¯ã¼ã«ã¼å ã§ãã¼ã¿ä¿åã®ããã«ä½¿ç¨ãããã¨ãã§ãã¾ãã
ãªã¯ã¨ã¹ãã«å¯¾ããã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãµã¤ãã®è³ç£ããã£ãã·ã¥ãããã®ã§ããµã¼ãã¹ã¯ã¼ã«ã¼ã«ãã£ãã·ã¥ãããã³ã³ãã³ãã使ã£ã¦ä½ãããããã«æç¤ºããå¿
è¦ãããã¾ãããã㯠fetch
ã¤ãã³ãã使ã£ã¦å®ç¾ã§ãã¾ãã
fetch
ã¤ãã³ããçºè¡ããããã³ãæå®ãããã¹ã³ã¼ãå
ã®ææ¸ã¨ãããã®ææ¸ãåç
§ãããã¹ã¦ã®ãªã½ã¼ã¹ãå«ãããµã¼ãã¹ã¯ã¼ã«ã¼ã«ãã£ã¦å¶å¾¡ããããªã½ã¼ã¹ã®åå¾ãã¾ãï¼ä¾ãã°ãindex.html
ãç»åãåãè¾¼ãããã«ãªãªã¸ã³éãªã¯ã¨ã¹ããè¡ãã¨ããµã¼ãã¹ã¯ã¼ã«ã¼ãééãã¾ãï¼ã
fetch
ã¤ãã³ããªã¹ãã¼ããµã¼ãã¹ã¯ã¼ã«ã¼ã«å²ãå½ã¦ãã¨ããã®ã¤ãã³ãä¸ã§ respondWith()
ãå¼ã³åºããã¨ã§ã HTTP ã¬ã¹ãã³ã¹ãä¹ã£åã£ã¦ã³ã³ãã³ããæ´æ°ãããã¨ãã§ãã¾ãã
self.addEventListener("fetch", (event) => {
event.respondWith(/* ã«ã¹ã¿ã ã³ã³ãã³ãã¯ãã¡ã */);
});
ããããã®ã±ã¼ã¹ã§ããããã¯ã¼ã¯ãªã¯ã¨ã¹ãã® URL ã¨ä¸è´ãããªã½ã¼ã¹ã§ã¬ã¹ãã³ã¹ãããã¨ããå§ãããã¨ãã§ããã
self.addEventListener("fetch", (event) => {
event.respondWith(caches.match(event.request));
});
caches.match(event.request)
ã¯ããããã¯ã¼ã¯ãããªã¯ã¨ã¹ããããåãªã½ã¼ã¹ãããã£ãã·ã¥ã«ããåçã®ãªã½ã¼ã¹ãå©ç¨å¯è½ã§ããã°ããããã³ã°ããããã¨ãã§ããããã«ãã¾ãããããã³ã°ã¯ãé常㮠HTTP ãªã¯ã¨ã¹ãã¨åæ§ã«ãURL ã¨æ§ã
ãªãããã¼ãä»ãã¦è¡ããã¾ãã
ã§ã¯ã caches.match(event.request)
ã¯ãµã¼ãã¹ã¯ã¼ã«ã¼ã®ãã£ãã·ã¥ã«ä¸è´ãããã®ãããå ´åã¯è¯ãã®ã§ãããä¸è´ããªãå ´åã¯ã©ãã§ããããï¼ãããä½ããã®å¤±æå¦çãæä¾ããªããã°ããããã¹ã¯ undefined
ã§è§£æ±ºãããä½ãè¿ãããªãã§ãããã
ãã£ãã·ã¥ããã®ã¬ã¹ãã³ã¹ããã¹ãããå¾ãé常ã®ãããã¯ã¼ã¯ãªã¯ã¨ã¹ãã«ãã©ã¼ã«ããã¯ãããã¨ãã§ãã¾ãã
const cacheFirst = async (request) => {
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
return fetch(request);
};
self.addEventListener("fetch", (event) => {
event.respondWith(cacheFirst(event.request));
});
ãã£ãã·ã¥ã«ãªããªã½ã¼ã¹ã¯ããããã¯ã¼ã¯ãããªã¯ã¨ã¹ãããã¾ãã
ãã£ã¨è¤éãªæ¦ç¥ãç¨ããã¨ããããã¯ã¼ã¯ãããªã½ã¼ã¹ãè¦æ±ããã ãã§ãªãããã£ãã·ã¥ã«ä¿åãã¦ãå¾ã§ãã®ãªã½ã¼ã¹ã«å¯¾ãããªã¯ã¨ã¹ãããªãã©ã¤ã³ã§åå¾ã§ããããã«ãããã¨ãã§ãã¾ããã¤ã¾ããStar Warsã®ã®ã£ã©ãªã¼ã«ç»åã追å ãããããã¢ããªãèªåçã«ç»åãåå¾ãã¦ãã£ãã·ã¥ãããã¨ãã§ããã®ã§ãã以ä¸ã¯ããã®ãããªæ¦ç¥ãå®è£ ããããã®ã¹ããããã§ãã
const putInCache = async (request, response) => {
const cache = await caches.open("v1");
await cache.put(request, response);
};
const cacheFirst = async (request) => {
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
const responseFromNetwork = await fetch(request);
putInCache(request, responseFromNetwork.clone());
return responseFromNetwork;
};
self.addEventListener("fetch", (event) => {
event.respondWith(cacheFirst(event.request));
});
ãªã¯ã¨ã¹ã URL ããã£ãã·ã¥ã«ãªãå ´åã await fetch(request)
ã§ãããã¯ã¼ã¯ãªã¯ã¨ã¹ããããªã½ã¼ã¹ããªã¯ã¨ã¹ããã¾ãããã®å¾ãã¬ã¹ãã³ã¹ã®ã¯ãã¼ã³ããã£ãã·ã¥ã«æ ¼ç´ãã¾ãã putInCache()
颿°ã¯ caches.open('v1')
㨠cache.put()
ã使ç¨ãã¦ããªã½ã¼ã¹ããã£ãã·ã¥ã«è¿½å ãã¾ããæ¬æ¥ã®ã¬ã¹ãã³ã¹ã¯ãã©ã¦ã¶ã¼ã«è¿ããããããå¼ã³åºãããã¼ã¸ã«æ¸¡ããã¾ãã
ãªã¯ã¨ã¹ãã¹ããªã¼ã ã¨ã¬ã¹ãã³ã¹ã¹ããªã¼ã ã¯ä¸åº¦ããèªã¿è¾¼ããªãã®ã§ãã¬ã¹ãã³ã¹ã®è¤è£½ã使ããå¿ è¦ãããã¾ãããã©ã¦ã¶ã¼ã«ã¬ã¹ãã³ã¹ãè¿ãã¦ãã£ãã·ã¥ã«å ¥ããã«ã¯ããããè¤è£½ããå¿ è¦ãããã¾ããã¤ã¾ãããªãªã¸ãã«ã¯ãã©ã¦ã¶ã¼ã«è¿ãããã¯ãã¼ã³ã¯ãã£ãã·ã¥ã«éããã¾ãããããã¯ããããä¸åº¦ã ãèªã¿è¾¼ã¾ãã¾ãã
å°ãå¥å¦ã«è¦ããã®ã¯ã putInCache()
ãè¿ããããã¹ãå¾
ã¡ç¶æ
ã§ãªããã¨ã§ããããããã®çç±ã¯ãã¬ã¹ãã³ã¹ã¯ãã¼ã³ããã£ãã·ã¥ã«è¿½å ãããã¾ã§ãã¬ã¹ãã³ã¹ãè¿ãã®ãå¾
ã¡ãããªãããã§ãã
ä»ããå¯ä¸ã®åé¡ã¯ããªã¯ã¨ã¹ãããã£ãã·ã¥ã«ä½ãä¸è´ããããããã¯ã¼ã¯ãå©ç¨ã§ããªãå ´åããã¯ããªã¯ã¨ã¹ãã¯å¤±æãã¦ãã¾ãã¨ãããã¨ã§ããä½ãèµ·ãã£ã¦ããã¦ã¼ã¶ã¼ã¯å°ãªãã¨ãä½ããå¾ããã¨ãã§ããããã«ãæ¢å®ã®ä»£æ¿å¦çãæä¾ãããã¨ã«ãã¾ãããã
const putInCache = async (request, response) => {
const cache = await caches.open("v1");
await cache.put(request, response);
};
const cacheFirst = async ({ request, fallbackUrl }) => {
// First try to get the resource from the cache
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
// Next try to get the resource from the network
try {
const responseFromNetwork = await fetch(request);
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
putInCache(request, responseFromNetwork.clone());
return responseFromNetwork;
} catch (error) {
const fallbackResponse = await caches.match(fallbackUrl);
if (fallbackResponse) {
return fallbackResponse;
}
// when even the fallback response is not available,
// there is nothing we can do, but we must always
// return a Response object
return new Response("Network error happened", {
status: 408,
headers: { "Content-Type": "text/plain" },
});
}
};
self.addEventListener("fetch", (event) => {
event.respondWith(
cacheFirst({
request: event.request,
fallbackUrl: "/gallery/myLittleVader.jpg",
}),
);
});
ãã®ä»£æ¿ç»åã鏿ããã®ã¯ã失æããå¯è½æ§ã®ããã¢ãããã¼ãã¯æ°ããç»åã ãã§ãä»ã®ãã¹ã¦ã¯å
ã«è¦ã install
ã¤ãã³ãã®ãªã¹ãã¼ã§ã®ã¤ã³ã¹ãã¼ã«ã«ä¾åãã¦ããããã§ãã
æå¹ã«ããã¨ãããã²ã¼ã·ã§ã³å èªã¿æ©è½ã¯ããã§ãããªã¯ã¨ã¹ãããªãããã¨ããã«ããµã¼ãã¹ã¯ã¼ã«ã¼ã®ã¢ã¯ãã£ãåã¨ä¸¦è¡ãã¦ãªã½ã¼ã¹ã®ãã¦ã³ãã¼ããéå§ãã¾ãã ããã«ããããµã¼ãã¹ã¯ã¼ã«ã¼ãã¢ã¯ãã£ãåããã¾ã§å¾ ã¤å¿ è¦ããªãããã¼ã¸ã¸ã®ããã²ã¼ã·ã§ã³ã§ããã«ãã¦ã³ãã¼ããéå§ãããããã«ãªãã¾ãã ãã®é å»¶ã¯æ¯è¼çç¨ã«ããçºçãã¾ããããçºçããå ´åã¯é¿ããããªããã®ã§ãããé大ãªãã®ã«ãªãå¯è½æ§ãããã¾ãã
ã¾ãããµã¼ãã¹ã¯ã¼ã«ã¼ã¢ã¯ãã£ãåæã« registration.navigationPreload.enable()
ã使ã£ã¦ãã®æ©è½ãæå¹ã«ããå¿
è¦ãããã¾ãã
self.addEventListener("activate", (event) => {
event.waitUntil(self.registration?.navigationPreload.enable());
});
ããã¦ãevent.preloadResponse
ã使ã£ã¦ fetch
ã¤ãã³ããã³ãã©ã¼ã®ä¸ã§å
èªã¿ããããªã½ã¼ã¹ã®ãã¦ã³ãã¼ããçµäºããã®ãå¾
ã¡ã¾ãã
åã®ç¯ã®ä¾ã«å¼ãç¶ãããã£ãã·ã¥ãã§ãã¯ã®å¾ã«å èªã¿ããããªã½ã¼ã¹ãå¾ æ©ããæåããªãã£ãå ´åã¯ãããã¯ã¼ã¯ããåå¾ããã³ã¼ããæ¿å ¥ãã¾ãã
æ°ããå¦çã¯æ¬¡ã®éãã§ãã
event.preloadResponse
ãå¾
ã¡ã¾ãããã㯠preloadResponsePromise
ã¨ã㦠cacheFirst()
颿°ã«æ¸¡ããã¾ããçµæãè¿ã£ã¦ããããããããã£ãã·ã¥ãã¾ããconst addResourcesToCache = async (resources) => {
const cache = await caches.open("v1");
await cache.addAll(resources);
};
const putInCache = async (request, response) => {
const cache = await caches.open("v1");
await cache.put(request, response);
};
const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => {
// First try to get the resource from the cache
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
// Next try to use (and cache) the preloaded response, if it's there
const preloadResponse = await preloadResponsePromise;
if (preloadResponse) {
console.info("using preload response", preloadResponse);
putInCache(request, preloadResponse.clone());
return preloadResponse;
}
// Next try to get the resource from the network
try {
const responseFromNetwork = await fetch(request);
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
putInCache(request, responseFromNetwork.clone());
return responseFromNetwork;
} catch (error) {
const fallbackResponse = await caches.match(fallbackUrl);
if (fallbackResponse) {
return fallbackResponse;
}
// when even the fallback response is not available,
// there is nothing we can do, but we must always
// return a Response object
return new Response("Network error happened", {
status: 408,
headers: { "Content-Type": "text/plain" },
});
}
};
// Enable navigation preload
const enableNavigationPreload = async () => {
if (self.registration.navigationPreload) {
await self.registration.navigationPreload.enable();
}
};
self.addEventListener("activate", (event) => {
event.waitUntil(enableNavigationPreload());
});
self.addEventListener("install", (event) => {
event.waitUntil(
addResourcesToCache([
"/",
"/index.html",
"/style.css",
"/app.js",
"/image-list.js",
"/star-wars-logo.jpg",
"/gallery/bountyHunters.jpg",
"/gallery/myLittleVader.jpg",
"/gallery/snowTroopers.jpg",
]),
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
cacheFirst({
request: event.request,
preloadResponsePromise: event.preloadResponse,
fallbackUrl: "/gallery/myLittleVader.jpg",
}),
);
});
ãã®ä¾ã§ã¯ããªã½ã¼ã¹ããé常ããã¦ã³ãã¼ããã¦ãå
èªã¿ãã¦ããåããã¼ã¿ããã¦ã³ãã¼ããã¦ãã£ãã·ã¥ãããã¨ã«æ³¨æãã¦ãã ããã代ããã«ãå
èªã¿æã«å¥ã®ãªã½ã¼ã¹ããã¦ã³ãã¼ããããã£ãã·ã¥ããããã«é¸æãããã¨ãã§ãã¾ãã詳細ã«ã¤ãã¦ã¯ãNavigationPreloadManager
> ã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãåç
§ãã¦ãã ããã
ãµã¼ãã¹ã¯ã¼ã«ã¼ã以åã«ã¤ã³ã¹ãã¼ã«ããã¦ãããããã¼ã¸ã®æ´æ°ãèªã¿è¾¼ã¿ã®æã«æ°ãããã¼ã¸ã§ã³ã®ã¯ã¼ã«ã¼ãå©ç¨ã§ããå ´åãæ°ãããã¼ã¸ã§ã³ã¯ããã¯ã°ã©ã¦ã³ãã§ã¤ã³ã¹ãã¼ã«ããã¾ãããã¾ã ã¢ã¯ãã£ãåãã¾ãããã¾ã å¤ããµã¼ãã¹ã¯ã¼ã«ã¼ã使ç¨ãã¦ããèªã¿è¾¼ã¾ãããã¼ã¸ããªããªã£ãããæ°ãããµã¼ãã¹ã¯ã¼ã«ã¼ãã¢ã¯ãã£ãåãã¾ãã
ã¡ã¢: Clients.claim()
ã使ç¨ãã¦ããããåé¿ãããã¨ãå¯è½ã§ãã
æ°ãããµã¼ãã¹ã¯ã¼ã«ã¼ã§ã install
ã¤ãã³ããªã¹ãã¼ããã®ãããªãã®ï¼æ°ãããã¼ã¸ã§ã³çªå·ãéç¥ãããã®ï¼ã«æ´æ°ããããªãã§ãããã
const addResourcesToCache = async (resources) => {
const cache = await caches.open("v2");
await cache.addAll(resources);
};
self.addEventListener("install", (event) => {
event.waitUntil(
addResourcesToCache([
"/",
"/index.html",
"/style.css",
"/app.js",
"/image-list.js",
// â¦
// æ°ãããã¼ã¸ã§ã³ã®ããã®æ°ããä»ã®ãªã½ã¼ã¹ãå
¥ãã¦ãã ãã...
]),
);
});
ãµã¼ãã¹ã¯ã¼ã«ã¼ãã¤ã³ã¹ãã¼ã«ãã¦ããéã以åã®ãã¼ã¸ã§ã³ã¯ã¾ã ãã§ããã«å¯¾ãã¦ã¬ã¹ãã³ã¹ãã¾ããæ°ãããã¼ã¸ã§ã³ã¯ãããã¯ã°ã©ã¦ã³ãã§ã¤ã³ã¹ãã¼ã«ããã¦ãã¾ãã以åã® v1
ãã£ãã·ã¥ã妨ããªãããã«ãæ°ãããã£ãã·ã¥ã v2
ã¨å¼ãã§ãã¾ãã
ã©ã®ãã¼ã¸ãååã®ãã¼ã¸ã§ã³ã使ç¨ãã¦ããªãã¨ããæ°ããã¯ã¼ã«ã¼ãæå¹åãããã§ããã«ã¬ã¹ãã³ã¹ããããã«ãªãã¾ãã
å¤ããã£ãã·ã¥ã®åé¤åã®ç¯ã§è¦ãããã«ããµã¼ãã¹ã¯ã¼ã«ã¼ãæ°ãããã¼ã¸ã§ã³ã«æ´æ°ããã¨ãããã® install
ã¤ãã³ããã³ãã©ã¼ã§æ°ãããã£ãã·ã¥ã使ãã¾ããååãã¼ã¸ã§ã³ã®ã¯ã¼ã«ã¼ã«ãã£ã¦å¶å¾¡ãããéãããã®ãã¼ã¸ããã䏿¹ã§ãååãã¼ã¸ã§ã³ã®ãã£ãã·ã¥ãå¿
è¦ãªã®ã§ã両æ¹ã®ãã£ãã·ã¥ãä¿æããå¿
è¦ãããã¾ããåã®ãã£ãã·ã¥ãããã¼ã¿ãåé¤ããã«ã¯ activate
ã¤ãã³ãã使ç¨ãã¾ãã
waitUntil()
ã«æ¸¡ããããããã¹ã¯ãå®äºããã¾ã§ä»ã®ã¤ãã³ãããããã¯ããã®ã§ãæ°ãããã£ãã·ã¥ä¸ã§åãã¦ã® fetch
ã¤ãã³ããåå¾ããã¨ãã«ã¯ãã¯ãªã¼ã³ã¢ããæä½ãå®äºãã¦ããã¨ç¢ºä¿¡ã§ãã¾ãã
const deleteCache = async (key) => {
await caches.delete(key);
};
const deleteOldCaches = async () => {
const cacheKeepList = ["v2"];
const keyList = await caches.keys();
const cachesToDelete = keyList.filter((key) => !cacheKeepList.includes(key));
await Promise.all(cachesToDelete.map(deleteCache));
};
self.addEventListener("activate", (event) => {
event.waitUntil(deleteOldCaches());
});
éçºè
ãã¼ã«
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4