使用 Service Worker 回應導覽要求,不必等待網路。
導覽要求是指瀏覽器在導覽列中輸入新網址,或點選頁面上的連結前往新網址時,瀏覽器提出的 HTML 文件要求。這正是 Service Worker 對效能影響最大的地方:如果您使用 Service Worker 回應導覽要求,而不等待網路,就能確保導覽速度穩定,且在網路無法使用時仍能保持彈性。與 HTTP 快取相比,這是 Service Worker 帶來的最大效能優勢。
如「識別從網路載入的資源」指南所述,導覽要求是網路流量「瀑布」中可能發出的多個要求中的第一個。透過導覽要求載入的 HTML 會啟動所有其他子資源 (例如圖片、指令碼和樣式) 要求的流程。
在 Service Worker 的 fetch 事件處理常式中,您可以檢查 FetchEvent 的 request.mode 屬性,判斷要求是否為導覽。如果設為 'navigate',則為導覽要求。
一般來說,請勿使用長期有效的 Cache-Control headers 快取導覽要求的 HTML 回應。通常應透過網路和 Cache-Control: no-cache 滿足這些要求,確保 HTML 以及後續網路要求鏈 (合理) 最新。如果使用者每次前往新頁面時都要連上網路,每次瀏覽可能都會變慢。至少可以確定,速度不會「穩定」。
不同的架構方法
如何回應導覽要求,同時避免網路連線,可能是一項棘手的問題。應採取何種做法,則取決於網站架構和使用者可能前往的不重複網址數量。
雖然沒有一體適用的解決方案,但以下一般準則應有助於您決定最可行的做法。
小型靜態網站
如果網頁應用程式包含相對少數 (例如數十個) 的不重複網址,且每個網址都對應到不同的靜態 HTML 檔案,則可行的做法是快取所有 HTML 檔案,並使用適當的快取 HTML 回應導覽要求。
使用預先快取功能,您可以在安裝 Service Worker 後立即預先快取 HTML,並在每次重建網站和重新部署 Service Worker 時更新快取的 HTML。
或者,如果您不想預先快取所有 HTML (可能是因為使用者通常只會前往網站上的部分網址),可以使用過時重新驗證執行階段快取策略。不過,請謹慎使用這種方法,因為每個 HTML 文件都會分開快取和更新。如果只有少數網址經常由同一組使用者重複造訪,且您認為這些網址可以獨立重新驗證,那麼最適合使用 HTML 的執行階段快取。
單一頁面應用程式
現代網頁應用程式經常採用單頁架構。其中,用戶端 JavaScript 會根據使用者動作修改 HTML。這個模型會使用 History API,在使用者與網頁應用程式互動時修改目前的網址,進而產生有效的「模擬」導覽。雖然 後續導覽可能是「假」的,但初始導覽是真實的,因此仍須確保網路不會封鎖初始導覽。
幸好,如果您使用單頁架構,可以遵循簡單的模式,從快取提供初始導覽:應用程式殼層。在這個模型中,無論要求的網址為何,Service Worker 都會傳回已預先快取的同一個 HTML 檔案,藉此回應導覽要求。這個 HTML 應為基本架構,可能包含一般載入指標或骨架內容。瀏覽器從快取載入這個 HTML 後,現有的用戶端 JavaScript 就會接管,並為原始導覽要求的網址轉譯正確的 HTML 內容。
Workbox 提供實作這種方法所需的工具;navigateFallback
option 可讓您指定要用作應用程式命令介面的 HTML 文件,以及選用的許可和拒絕清單,將此行為限制在網址子集。
多頁應用程式
如果網路伺服器會動態產生網站的 HTML,或您有數十個以上的不重複網頁,則在處理導覽要求時,就很難避免網路。「其他」中的建議可能適用於您。
不過,對於特定多頁應用程式,您可以實作 Service Worker,完整複製網路伺服器用於產生 HTML 的邏輯。如果能在伺服器和 Service Worker 環境之間共用轉送和範本資訊,這種做法的效果最好,特別是當網路伺服器使用 JavaScript (不依賴 Node.js 專屬功能,例如檔案系統存取權) 時。
如果您的網路伺服器屬於該類別,且您想探索將 HTML 產生作業從網路移至 Service Worker 的方法,請參閱「超越 SPA:PWA 的替代架構」中的指南,開始著手。
其他
如果您無法使用快取的 HTML 回應導覽要求,請務必採取步驟,確保在網站中新增 Service Worker (用於處理其他非 HTML 要求) 不會導致導覽速度變慢。啟動 Service Worker 但不使用它來回應導覽要求,會造成少量延遲 (如「使用 Service Worker 建構更快速、更具彈性的應用程式」一文所述)。如要減少這項負擔,您可以啟用導覽預先載入功能,然後使用fetch事件處理常式中預先載入的網路回應。
Workbox 提供輔助程式庫,可偵測是否支援導覽預先載入功能,如果支援,則可簡化指示 Service Worker 使用網路回應的程序。