預先快取注意事項'ts

這份文件先前介紹過快取程序,但對於如何正確執行這項動作仍不夠明確。這點十分重要,因為無論您是否使用 Workbox,都可以輕鬆預先快取過多資料,且可能會浪費資料和頻寬。請務必謹慎預先快取酬載對使用者體驗的影響。

閱讀這份文件時,瞭解這些是一般性準則。您的應用程式架構和需求可能規定要採取的行動與此處建議的不同,但這些準則可以做為預設值使用。

建議做法:預先快取重要靜態資產

最適合預先快取是關鍵的靜態資產,但何者才是「重要」資產?從開發人員的角度來看,您可能會想將整個應用程式視為「關鍵」,但使用者的意見才是最重要的。請將關鍵素材資源視為提供使用者體驗所需的內容:

  • 全域樣式表。
  • 提供全域功能的 JavaScript 檔案。
  • 應用程式殼層 HTML (如果適用於您的架構)。

提醒:以上是一般指南,並非硬性建議。預先快取素材資源時,最好在預先快取旁邊執行,不要過度。

建議做法:預先快取多網頁網站的離線備份資料

如果是一般多頁網站,您可能需要使用以網路為優先僅限網路的快取策略來處理導覽要求。

在這種情況下,您需要確保服務工作處理程序能預先快取,並在使用者離線提出瀏覽要求時傳回離線備用網頁。在 Workbox 中執行此動作的其中一種方法是,將純網路策略與離線備用項目搭配使用,並善用導覽預先載入功能:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute, Route} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
import * as navigationPreload from 'workbox-navigation-preload';

navigationPreload.enable();

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

// The network-only callback should match navigation requests, and
// the handler for the route should use the network-only strategy, but
// fall back to a precached offline page in case the user is offline.
const networkOnlyNavigationRoute = new Route(({request}) => {
  return request.mode === 'navigate';
}, new NetworkOnly({
  plugins: [
    new PrecacheFallbackPlugin({
      fallbackURL: '/offline.html'
    })
  ]
}));

registerRoute(networkOnlyNavigationRoute);

這樣可確保使用者在離線狀態下瀏覽未儲存在快取中的網頁,可以取得一些離線內容。

也許可以:考慮使用推測性預先快取

這可說是相當大的「可能」,但預先快取素材資源仍能帶來助益,而且只會用於特定情況。您不妨這樣思考:使用者會為了提前下載資料而產生一些額外的資料下載次數,這對於加快日後資產請求的推測優勢。

在此提醒您,請務必謹慎決定。這麼做很容易浪費資料,因此應做為資料導向決策。此外,請避免以推測性的方式預先快取經常變更的資產,因為每當上述程式碼偵測到新的修訂版本,使用者就會產生額外的數據用量。在數據分析中觀察使用者流程,瞭解使用者傾向於何處。如果您對投機性預存素材資源有任何疑問,這可能不是的好方法。

可能不符合:預先快取靜態 HTML

本指南適用於靜態網站,其中的獨立 HTML 檔案是由靜態網站產生器產生或手動建立,而不是由動態產生或由應用程式後端提供。如果這就是您的架構,則建議您「不」預先快取網站的每個 HTML 檔案。

預先快取整個網站的 HTML 檔案有一個問題,就是系統現在一律會在 Service Worker 更新前,從快取提供預先快取的標記。這種做法可以提升效能,但如果網站的 HTML 經常變更,可能會導致快取大幅流失。

但這項規則有一些例外,如果你要部署的小型網站含有幾個靜態 HTML 檔案,建議你預先快取所有網頁,讓這些網頁可供離線使用。如果你的網站規模特別龐大,建議你推測幾個高價值網頁和離線備用網頁,然後透過執行階段快取來快取其他網頁。

請避免:預先快取回應式圖片或網站小圖示

這比較不像一般準則,大致上是規則。回應式圖片是相當複雜的解決方案,能夠解決複雜的問題:有許多使用者的裝置運用,每種裝置的螢幕大小、像素密度和支援替代格式都有所不同。如果您預先快取整組回應式圖片,使用者可能只下載了其中一張圖片,就可能已預先快取好幾張圖片。

網站小圖示也有類似的情況,因為網站經常針對不同情境部署整組網站小圖示。在大多數情況下,網站小圖示往往只會要求使用一個網站小圖示,導致預先快取整個網站小圖示組合也相當浪費。

請為使用者提供喜好,不要預先快取回應式圖片和網站小圖示集。建議您改用執行階段快取。如果您必須預先快取圖片,請預先快取廣泛使用的圖片 (不屬於一組回應式圖片或網站小圖示)。可擴充向量圖形在數據用量方面的風險較低,無論特定螢幕的像素密度為何,單一 SVG 都能以最佳方式算繪內容。

請勿:預先快取 polyfill

對 API 而言,對 API 的支援是一項持續不斷的挑戰,而 Polyfill 是克服挑戰的方式之一。將 polyfill 的效能成本降至最低的方法之一,就是進行功能檢查,並只為需要這些程式碼的瀏覽器載入 polyfill。

因為有條件地載入 polyfill 作業會在執行階段期間,按照目前的環境進行,因此預先快取 polyfill 是一種遊戲。有些使用者會因此受益,有些人則會浪費頻寬處理不必要的 polyfill。

請勿預先快取 polyfill。請仰賴執行階段快取,確保應用程式只會在需要快取的瀏覽器中快取,以免造成資料浪費。

結語

要做到準備,就得先思考使用者實際需要的資產,但是只要能優先考量未來的效能和可靠性,絕對能做到這點。

如果不確定是否應預先快取特定資產,最好的方式是要求 Workbox 排除這些資產,並建立執行階段快取路徑來處理這些資源。無論採取哪一種方式,這份說明文件的後續部分將詳細說明預先快取,日後您就能將這些原則套用至預先快取邏輯。