快取中

快取儲存空間是一項強大的工具,這樣一來,應用程式就不會那麼依賴網路狀況。善用快取可讓網路應用程式離線運作,並在任何網路狀況下盡快提供資產。如「資產和資料」一文所述,您可以決定快取必要資產的最佳策略。如要管理服務工作人員互動的快取,請使用 Cache Storage API

Browser Support

  • Chrome: 43.
  • Edge: 16.
  • Firefox: 41.
  • Safari: 11.1.

Source

Cache Storage API 可從不同環境取得:

  • 視窗環境 (PWA 的主執行緒)。
  • Service Worker。
  • 您使用的任何其他工作人員。

使用 Service Worker 管理快取的優點之一,是其生命週期不會與視窗綁定,因此不會封鎖主執行緒。請注意,如要使用 Cache Storage API,大多數情境都必須採用 TLS 連線。

要快取的內容

您可能會先想到要快取哪些內容。雖然這個問題沒有單一答案,但您可以先從算繪使用者介面所需的所有最低資源開始。

這些資源應包括:

  • 主要網頁 HTML (應用程式的 start_url)。
  • 主要使用者介面所需的 CSS 樣式表。
  • 使用者介面中使用的圖片。
  • 用於算繪使用者介面的必要 JavaScript 檔案。
  • 用於呈現基本體驗的資料,例如 JSON 檔案。
  • 網頁字型。
  • 在多頁面應用程式中,您要快速或離線提供的其他 HTML 文件。

可離線使用

雖然離線功能是漸進式網頁應用程式的必要條件之一,但請務必瞭解,並非所有 PWA 都需要完整的離線體驗,例如雲端遊戲解決方案或加密資產應用程式。因此,您可以提供基本使用者介面,引導使用者處理這些情況。

PWA 不應顯示瀏覽器的錯誤訊息,指出網頁轉譯引擎無法載入網頁。請改用服務工作人員顯示自己的訊息,避免出現一般且令人困惑的瀏覽器錯誤。

視 PWA 的需求而定,您可以使用許多不同的快取策略。因此,請務必設計快取使用方式,提供快速且穩定的體驗。舉例來說,如果所有應用程式資產都能快速下載、不會佔用大量空間,且不需要在每次要求時更新,那麼快取所有資產就是有效的策略。另一方面,如果資源必須是最新版本,您可能完全不想快取這些資產。

使用 API

使用 Cache Storage API 在來源中定義一組快取,每個快取都以您定義的字串名稱識別。透過 caches 物件存取 API,並使用 open 方法建立快取,或開啟已建立的快取。open 方法會傳回快取物件的 Promise。

caches.open("pwa-assets")
.then(cache => {
  // you can download and store, delete or update resources with cache arguments
});

下載及儲存資產

如要要求瀏覽器下載及儲存資產,請使用 addaddAll 方法。add 方法會發出要求並儲存一個 HTTP 回應,而 addAll 則會根據要求或網址陣列,將一組 HTTP 回應儲存為交易。

caches.open("pwa-assets")
.then(cache => {
  cache.add("styles.css"); // it stores only one resource
  cache.addAll(["styles.css", "app.js"]); // it stores two resources
});

快取儲存介面會儲存整個回應,包括所有標頭和內文。因此,您稍後可以使用 HTTP 要求或網址做為鍵來擷取該值。具體做法請見「提供服務」章節

快取時機

在 PWA 中,您可以決定何時要快取檔案。其中一種做法是在安裝 Service Worker 時盡可能儲存大量資產,但通常不是最佳做法。快取不必要的資源會浪費頻寬和儲存空間,且可能導致應用程式提供非預期的過時資源。

您不需要一次快取所有資產,可以在 PWA 的生命週期內多次快取資產,例如:

  • 在安裝 Service Worker 時。
  • 首次載入網頁後。
  • 使用者前往某個區段或路徑時。
  • 網路處於閒置狀態時。

您可以在主執行緒或 Service Worker 環境中,要求快取新檔案。

在 Service Worker 中快取資產

最常見的情況之一,是在安裝 Service Worker 時,快取最少量的資產。如要這麼做,您可以在 Service Worker 的 install 事件中使用快取儲存空間介面。

由於服務工作人員執行緒隨時可能停止,您可以要求瀏覽器等待 addAll Promise 完成,提高儲存所有資產的機會,並確保應用程式一致性。以下範例說明如何使用服務工作人員事件監聽器中收到的事件引數 waitUntil 方法,執行這項操作。

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
   event.waitUntil(
      caches.open("pwa-assets")
      .then(cache => {
         return cache.addAll(urlsToCache);
      });
   );
});

waitUntil() 方法會接收 Promise,並要求瀏覽器等待 Promise 中的工作解析 (已完成或失敗),再終止 Service Worker 程序。您可能需要串連 Promise,並傳回 add()addAll() 呼叫,讓單一結果傳送至 waitUntil() 方法。

您也可以使用 async/await 語法處理 Promise。在這種情況下,您需要建立可呼叫 await 的非同步函式,並在呼叫後將 Promise 傳回至 waitUntil(),如下列範例所示:

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
   let cacheUrls = async () => {
      const cache = await caches.open("pwa-assets");
      return cache.addAll(urlsToCache);
   };
   event.waitUntil(cacheUrls());
});

跨網域要求和不透明回應

PWA 可以從來源和跨網域下載及快取資產,例如第三方 CDN 的內容。如果是跨網域應用程式,快取互動方式與同源要求非常相似。系統會執行要求,並將回應副本儲存在快取中。與其他快取資產一樣,這項資產只能在應用程式來源中使用。

資產會儲存為不透明的回應,也就是說,您的程式碼無法查看或修改該回應的內容或標頭。此外,不透明的回應不會在 Storage API 中顯示實際大小,因此會影響配額。部分瀏覽器會顯示較大的大小,例如 7 MB,即使檔案只有 1 KB 也是如此。

更新及刪除資產

您可以使用 cache.put(request, response) 更新資產,並使用 delete(request) 刪除資產。

詳情請參閱 Cache 物件說明文件

偵錯快取儲存空間

許多瀏覽器都提供方法,讓您在開發人員工具的「應用程式」分頁中,偵錯快取儲存空間的內容。您可以在這裡查看目前來源中每個快取的內容。我們會在「工具和偵錯」一章中,進一步說明這些工具。

Chrome 開發人員工具偵錯快取儲存空間內容。

資源