iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 10
4
Modern Web

30 天 Progressive Web App 學習筆記系列 第 10

Day 10 - 30 天 Progressive Web App 學習筆記 - Service Work 簡介

今天筆記的是 Service Worker 的觀念,較深入的部份將會在之後的文章,透過實作再來做細部說明。

Service Worker 是非常強大的 offline caching,讓使用者可以重複使用 cache,即時顯示畫面在網站或應用程式裡,提供優異的效能。

Service Worker 解決了 WEB 用戶無法離線瀏覽的問題,當網站處於離線狀態,沒有辦法利用網路得到更多資料之前,仍然可以提供基本體驗,讓網站更像 Native App、可以提供像是定期更新、推播通知等功能。

Service Workers 不能直接操作 DOM,但是可以通過 postMessage,把消息傳送給頁面,讓頁面去操作 DOM。

Service Worker,在瀏覽器的背景默默地執行,不需要透過網頁的操作觸發,Service Worker 有著自己的生命週期,為了使用 Service Worker,你的網站必須使用 Javascript 進行註冊,並且必須在 localhost 或 HTTPS 的環境底下,才能運行。

生命週期

Service Worker 擁有一個完全獨立於 WEB 的生命週期,我們來了解 Service Worker 究竟是如何運作的?

  1. 使用 Service Worker:

    • 為了使用 Service Worker,你的網站必須使用 Javascript 進行註冊
  2. 註冊 Service Worker 之後,瀏覽器會在背景啟動一個 Service Worker 的安裝。

    • 成功:在安裝過程裡,瀏覽器會下載/緩存一些靜態資源,當所有的資源都緩存成功,那麼代表 Service Worker 安裝成功,進入 Activated。
    • 失敗:若有其中一項資源下載/緩存失敗,則整個安裝過程失敗,Service Worker 進入 Error,等待下次安裝。
  3. Service Worker 進行接管頁面。

  4. 接管頁面之後做處理:

    • 當頁面沒有被使用的時候,Service Worker 會進入停止(Terminated)的狀態,節省記憶體。
    • 當網頁有發送 request 或 message(頁面發送一個消息) 時,就會去攔截所有 HTTP 請求或 message 事件,做相對應的處理。

Service Worker 實作步驟

  • Registering the Service Worker
    • 實作 Service Worker 之前,必須先註冊 Service Worker,才能夠執行 Service Worker 的生命週期
  • Setting up the Default Cache
    • 在 Service Worker 的 install 事件裡,設定預期 cache 路徑,儲存 App Shell 檔案
  • Clearing Old Cache
    • 一開始在 fetch 執行之前,會先觸發 activate 事件,我們可以在這個週期進行清除快取的動作,避免網站會一直存取舊的 cache 檔案
  • Handling Fetch Requests
    • 無論是儲存 App Shell 檔案或者是 API 內容,都需要透過 fetch 這個事件去處理攔截到的 Request 並回傳 Response,讓網站處於沒有網路時、仍然可以進行離線瀏覽。

簡單實作

跟著官方教程來講解一個簡單的 Service Worker 是如何運作?

首先我們觀察以下 HTML 的內容,透過 Javascript 註冊 Service Worker,並設定 3 秒後,要顯示一張『狗狗』的圖片。

<!DOCTYPE html>
An image will appear here in 3 seconds:
<script>
  navigator.serviceWorker.register('/sw.js')
    .then(reg => console.log('SW registered!', reg))
    .catch(err => console.log('Boo!', err));

  setTimeout(() => {
    const img = new Image();
    img.src = '/dog.svg';
    document.body.appendChild(img);
  }, 3000);
</script>  

接著來看 Service Worker 的檔案(sw.js):

self.addEventListener('install', event => {
  console.log('V1 installing…');

  // cache a cat SVG
  event.waitUntil(
    caches.open('static-v1').then(cache => cache.add('/cat.svg'))
  );
});

self.addEventListener('activate', event => {
  console.log('V1 now ready to handle fetches!');
});

self.addEventListener('fetch', event => {
  const url = new URL(event.request.url);

  // serve the horse SVG from the cache if the request is
  // same-origin and the path is '/dog.svg'
  if (url.origin == location.origin && url.pathname == '/dog.svg') {
    event.respondWith(caches.match('/cat.svg'));
  }
});

可以參考這個 DEMO 並開啟 console 觀察,發現第一次載入時,會運行:

<script>
  navigator.serviceWorker.register('/sw.js')
    .then(reg => console.log('SW registered!', reg))
    .catch(err => console.log('Boo!', err));

  setTimeout(() => {
    const img = new Image();
    img.src = '/dog.svg';
    document.body.appendChild(img);
  }, 3000);
</script> 

網頁上等待三秒後,出現一張『狗狗』的圖片。
console 內會顯示 V1 installing…SW registered! 最後出現 V1 now ready to handle fetches! 資訊,執行 install(cache a cat SVG)和 activate 階段。

再次透過 console 觀察,重新整理後,Service Worker 就會攔截到圖片的 request,並置換成 『貓咪』的圖片。

參考文件

結語

今天筆記了 Service Worker 的用途以及生命週期,透過簡單的範例去了解基本的運作原理。

Service Worker 會影響網頁的行為,之後會再接下來的文章中,講解如何實作 Service Worker,而下一篇要分享如何使用 Chrome devTools 檢視 Service Worker 等狀態。


本人小小筆記,如有錯誤或需要改進的部分,歡迎給予回饋。
我將會用最快的速度修正,m(_ _)m。謝謝

上一篇
Day 09 - 30 天 Progressive Web App 學習筆記 - Optimizing Content Efficiency
下一篇
Day 11 - 30 天 Progressive Web App 學習筆記 - Chrome devTools - Introducing the Application tab
系列文
30 天 Progressive Web App 學習筆記30

1 則留言

0
若虛
iT邦新手 5 級 ‧ 2018-12-03 11:18:04

回報:生命週期標題下的第一張圖已經失效。

我要留言

立即登入留言