快取中

快取儲存空間是一項強大的工具。這可讓應用程式較不容易受到網路狀況的影響。只要妥善運用快取,您就能讓網路應用程式在離線狀態下運作,並在任何網路狀況下盡可能快速地提供素材資源。如素材資源和資料一文所述,您可以決定最佳的快取必要素材資源策略。如要管理快取,服務 worker 會與 Cache Storage API 互動。

瀏覽器支援

  • Chrome:43。
  • 邊緣:16。
  • Firefox:41。
  • Safari:11.1。

資料來源

您可以在不同情境下使用 Cache Storage API:

  • 視窗內容 (PWA 的主執行緒)。
  • Service Worker。
  • 您使用的任何其他工作站。

使用服務工作者管理快取的優點之一,就是其生命週期不會與視窗綁定,也就是說不會封鎖主執行緒。請注意,如要使用 Cache Storage API,這些情境大多必須在 TLS 連線下執行。

快取內容

您可能會想知道快取內容的首要問題是,雖然這個問題沒有單一答案,但您可以先從所有必要資源著手,這些資源是您轉譯使用者介面所需的。

這些資源應包含:

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

可離線使用

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

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

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

使用 API

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

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 中,您可以決定快取檔案的時機。雖然在安裝服務工作者時盡可能儲存大量素材資源是一種方法,但通常不建議這麼做。快取不必要的資源會浪費頻寬和儲存空間,並可能導致應用程式提供不必要的過時資源。

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

  • 服務工作者安裝時。
  • 首次載入網頁後。
  • 使用者前往某個部分或路線時。
  • 網路閒置時。

您可以在主執行緒或服務工作者內容中要求快取新檔案。

在 Service Worker 中快取資產

最常見的情況之一,是當服務工作站安裝時,快取最少的資產集合。如要這麼做,您可以在服務工作者中的 install 事件中使用快取儲存空間介面。

由於服務工作者執行緒可隨時停止,您可以要求瀏覽器等待 addAll 應許完成,以便增加儲存所有資產的機會,並維持應用程式的一致性。以下範例示範如何使用服務工作者事件事件監聽器收到的事件引數 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() 方法會接收承諾,並要求瀏覽器等待承諾中的任務解決 (完成或失敗),然後再終止服務工作程式程序。您可能需要鏈結承諾並傳回 add()addAll() 呼叫,以便單一結果傳送至 waitUntil() 方法。

您也可以使用 async/await 語法處理承諾。在這種情況下,您需要建立非同步函式,以便呼叫 await,並在呼叫後傳回承諾給 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 的內容。在跨網域應用程式中,快取互動與相同來源要求非常相似。系統會執行要求,並將回應的副本儲存在快取中。與其他快取的素材資源一樣,這類素材資源只能在應用程式的來源中使用。

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

更新及刪除資產

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

詳情請參閱「快取物件說明文件」。

偵錯快取儲存空間

許多瀏覽器都提供一種方法,可在 DevTools 應用程式分頁中對快取儲存空間的內容進行偵錯。您可以在該頁面中查看目前來源中的每個快取內容。我們會在「工具和偵錯」一章中進一步介紹這些工具。

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

資源