iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
4

PWA 的重點就是這個 Service Worker 了,可以做到離線還能使用,主要都是靠它在幫忙。這個 Service Worker 到底有什麼厲害的呢?

雖然 Chrome OS 是個都在線上使用的作業系統,畢竟你上網站收 email、看影片都要有網路。不過雖然很少離線,但 Chrome OS 也不至於成為一塊廢鐵,還是有許多可以操作的 App,這個靠的就是 Android App 和 PWA。PWA 可以離線使用的部分,先前已經有示範過了。你可以到 https://bookpwa.noob.tw,這是一個範例訂房網站,一開始先把所有的房間點一點,斷開網路後重新打開網站,你還是可以點進那些房間的詳細資訊。

你可以閱讀 之前的文章 看到我們是怎麼調整 sw-config 的。不過當時是使用 sw-precache 套件,其實也只用了快取的部分,今天來談談 Service Worker 可以做到什麼。

Service Worker 是什麼

JavaScript 其實是一個 Single Thread 的語言。雖然大多數非同步、Callback、Promise 語法好像不會卡到主要畫面,但其實它還是只有一個執行緒,例如你寫了一個巨大的 Node.js 程式,耗了很多 CPU 資源,你用 htop 查看,它還是只用了一個核心。

因此,網頁開始有了 Web Workers、Node.js 開始有了 Worker Threads。Web Workers 可以在背景執行緒中執行你的程式,而不會卡住主要執行緒(也就不會卡住使用者介面)。通常我們會拿 Web Worker 進行比較久的 Fetch 請求,甚至是執行 WebAssembly 程式,。Web Workers 之間可以透過事件傳遞狀態,也可以透過參考的方式傳遞大陣列(如 Uint8Array)。

Service Worker 和 Web Worker 有點像,卻又不完全相同。雖然一樣會多使用一條執行緒,但 Service Worker 主要當作瀏覽器和網路之間的 Proxy,你可以去監聽 fetch 事件,從中操縱網路請求的結果。而 Service Worker 在這個頁面關掉後,會持續運作。

Service Worker 的事件

這篇不要談太多程式碼,稍微講一下它可以幹嘛就好了。

還記得 Progressive Enhancement 嗎?設備再怎麼爛,就算不支援 Service Worker,你也要讓它可以看這個網頁。所以一開始要先檢查瀏覽器是不是支援 Serivce Worker:

if ('serviceworker' in navigator) {
    // 可以用
}

可以用的話才是開始註冊→下載→安裝→啟用。一旦網頁上呼叫註冊 Service Worker(以下簡稱 SW) 後,瀏覽器就會馬上開始下載 SW,並嘗試安裝,安裝成功之後就會馬上被啟用。但是,如果舊版的 SW 還沒被淘汰的話,新版的 SW 就算安裝了也不會馬上啟用。

這候除了等 SW 自己被淘汰以外,也可以去監聽 SW 被安裝啟用的狀態。寫法就像一般的事件:

this.addEventListener('install', (event) => {
    // 安裝後要觸發的事情
});

'install' 改成 'activate' 就是啟用的事件。你可以在這邊要求 SW 快取你的網站會用到的靜態資源或資料,也可以在這邊解決掉舊的 SW。

前面說到 SW 和 Web Workers 最大的差別就是,SW 通常用來當作 Proxy,這時候我們就可以來監聽 fetch 事件。例如你可以在這邊先用 caches.match 來檢查是否已經有已被快取的資源,並直接回傳已快取的資源、取消請求;如果 caches.match 不到,那就在回傳的時候拿一份放進快取裡面。這種方法除了在離線時也能確保資源可以使用外,在一些特殊的應用上也可以這樣節省流量。如果你擔心快取會讓使用者沒辦法吃到最新的內容的話,SW 也可以聽取 Background Sync 事件,簡單來說就是當網路恢復的時候會觸發的事件。

SW 還可以拿來做通知,也就是 Push Notification 事件。你不需要 SW 就可以拿來做通知了,不過透過 Push Notification,你可以在使用者沒有開啟你的網站的情況下推送通知給使用者,而且會透過 FCM 等伺服器、公私鑰加密等方法,確保不會有邪惡的第三者發送通知給你的使用者。另外使用者點下通知的時候不是在網頁上,可能是 Android 通知、Chrome OS 通知或 Windows 通知等,SW 也支援監聽 Notification Interaction 事件,你可以在使用者點擊通知後跳出某個網站、顯示一個動畫、從快取載入東西等等。

結語

以上大概是 Service Worker 可以做到的事情,需要注意的是 Service Worker 只會在 HTTPS 環境下或是 Localhost 才會作用,你可以使用 ngrok 來救援,或是推到 GitHub Pages 等地方來測試。而如果要檢查 Service Worker 是否正常執行,DevTools 也是你的好幫手。

https://ithelp.ithome.com.tw/upload/images/20200929/20119970dR2VwP7jhY.png

本篇文章同步發表在 Noob's Space


上一篇
PWA 體驗設計:介面以外,看不到的還有更多
下一篇
PWA:用 Manifest 定義 App 的名稱
系列文
用 Chromebook 能寫什麼樣的東西30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言