iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
Modern Web

你知道這是什麼嗎? Chrome Extension MV3 With Vite系列 第 7

# 你知道這是什麼嗎? Chrome extension MV3 With Vite - Day7 Service Worker 離線快取

  • 分享至 

  • xImage
  •  

Hi Dai Gei Ho~ 我是Winnie ~ 延續昨的主題,我們介紹了Service Worker的運作,接著此篇文章中我們要透過簡單實作離線快取進一步的了解Service Worker生命週期及 fetch攔截請求 的應用。

註冊 Service Worker

在昨天文章中我們有提到,如要在網站中使用 Service Worker 需透過navigator.serviceWorker.register方法進行註冊,而此方法為一個Promise,可以捕獲成功失敗來進行下ㄧ步處理。

同時在註冊 Service Worker 時,需注意註冊檔案的存放路徑,因為存放的位置 會決定 Service Worker的 作用範圍。

舉例來說:

如將sw.js放置於example.com/根目錄下,此時 service worker 即可存取資料的範圍為example.com/中的資料,

相反地,如果example.com/users/index.html,就無法進行存取。

// main.js

  if('serviceWorker' in  navigator ){
    navigator.serviceWorker.register("/sw.js")
      .then( registration => {
          // console.log('SW is reqistration', registration)  
      })
      .catch( err => console.log('SW reqistration failed :', err))
  } else {
    console.log('Sw is not supported!')
  }
  

雖然在各Browser中針對service worker大多都已經支援,但為了以防萬一,我們可以在註冊前來檢查 Browser中 是否支援,減少Browser中的記憶體資源消耗。

註冊成功後,初次會觸發 install 事件,進行靜態資源快取

在註冊成功後,在Service Worker 中會觸發 install 事件,透過event.waitUntil()來延長install 事件此時我們就可以進行靜態資源快取,接著,使用caches.open()設置一個cache的空間將需要cache的資料,透過cache.addAll(Array) 或著 cache.add(String)來儲存。

caches.add(String) 、cache.addAll(Array) 為 新增 cache

let version ='V1';

self.addEventListener('install', e => {
  console.log('SW is install!');
  e.waitUntil(
    caches.open(version).then(cache => cache.addAll([
    "/", "index.html" , "main.js", "main.css" 
    ]))
  );
});

https請求觸發 Fetch 事件,針對攔截請求處理資料

透過Fetch事件攔截 https 請求,如果再cach中有緩存目前相請求資料就是 return 目前快取的資源,沒有就進行原本的請求。

caches.match 為 查詢 cache

self.addEventListener('fetch', (e)=>{
    e.respondWith(caches.match(e.request).then(res =>{
        if (res) {
            return res
        } else {
           return fetch(event.request)
        }
    })
 

咦?那有些資源不是馬上會使用到,沒有全部進快取 怎麼辦?

此時可以透過fetch 事件觸發時的方法,將一開始沒有快取的資源 cache.put() 放入原本定義的cache版本中。

//略..
fetch(event.request)
   .then((es=>{
       caches.open(version)
       .then((cache)=>{
           cache.put(e.request.url, res.clone());
               return res;
           })
       });

刪除舊版快取

但你知道的,不管什麼事總會有變變變的時候

假設快取新增了不同版本,造成新舊快取同時存在,此時在抓取相同資源時,就會遇到有版本的問題。

所以我們可以透過 Service Worker中的sw.js每次都會被執行的特性,更新 快取版本。

let version ='V2';

self.addEventListener('install', e => {
  console.log('SW is install!');
  e.waitUntil(
    caches.open(version).then(cache => cache.addAll([
    "/", "index.html" , "main.js", "main.css" 
    ]))
  );
  this.skipWaiting()
});


self.addEventListener('activate', e => {
  console.log("activate")
  let delFn = caches.keys().then((cacheList) => {
    return Promise.all(
      cacheList.map((cacheName)=>{
        if (cacheName !== verson) {
          return caches.delete(cacheName);
        }
      })
    );
  })
  
  e.waitUntil(Promise.all([delFn])
    .then(() => {
      return self.clients.claim()
    })
  )
});

透過在install事件中調用 self.skipWaiting()方法,直接觸發當activate 事件,進行快取版本的比對,如果cache 名字 與 新版不符,就進行刪除,最後使用self.clients.claim()更新快取。

以上就是關於 Service Worker 常見功能 離線緩存 實作介紹(,而在下篇文章中將繼續來介紹 Service Worker 另一個常見功能 訂閱推播 (本來是預計一篇文章,但真的說不完。

那今天文章先到這邊了,謝謝願意花時間看此篇文章的你,如果文章有錯誤的地方,再麻煩不吝嗇的給予指教,感謝!!

每日有感而發:

今天想分享一首每天一定會聽的歌 -> OKDAL - Hero 히어로
每當聽到這首歌 就會想到 一個人在韓國七天的那段時間
不用跟任何人說話 走啊走啊走的 好平靜


上一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day6 關於Service Worker
下一篇
你知道這是什麼嗎? Chrome extension MV3 With Vite - Day8 Service Worker 訂閱推播
系列文
你知道這是什麼嗎? Chrome Extension MV3 With Vite30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言