當服務工作處理程序處理 fetch
事件時,瀏覽器會等待 Service Worker 提供回應,雖然網路要求的延遲時間是等待時間的重要因素,但瀏覽器可能也需要等待 Service Worker 啟動並觸發 fetch
事件回呼。
開機時間會因裝置和功能而異,但所需時間可能相當龐大,如果 CPU 速度緩慢,或是因為環境條件的關係,啟動作業處於受限狀態,有時最長可達半秒。透過 Cache
執行個體提供導覽回應時,避開網路的效能提升幅度可能會超過這個啟動時間。針對傳送至網路的導覽要求,導入 Service Worker 可能會產生明顯的延遲。
輸入導覽預先載入功能
導覽預先載入是一項 Service Worker 功能,可解決服務工作站開機時間造成的延遲。如未啟用導覽預先載入功能,服務工作處理程序的開機程序和應處理的瀏覽要求都會連續發生:
這並非理想的做法,但只要啟用導覽預先載入功能,即可確保 Service Worker 開機和瀏覽要求會同時發生,藉此修正此問題:
瀏覽預先載入功能可有效最佳化使用 Service Worker 的網站,但並非在所有情況下都應啟用的功能。具體來說,使用友善快取應用程式殼層的網站不需要瀏覽預先載入,因為快取會將導覽要求提供給應用程式殼層標記,不會發生任何瀏覽延遲。在這些情況下,預先載入的回應會遭到浪費,但成效不佳。
網站無法預先載入 HTML 時,最適合使用導覽預先載入功能。試想網站中的標記回應是動態的,且會隨著驗證狀態等等變化。這類的導覽要求可能會使用網路優先 (或甚至僅限網路) 策略,這時導覽預先載入功能可能會產生巨大的差異。
在 Workbox 中使用導覽預先載入功能
直接在非 Workbox 技術的 Service Worker 中使用導覽預先載入,相當不容易。首先,並非所有瀏覽器都支援這個註解。其次,想做出正確做法並不容易。如要瞭解如何直接使用這項工具,請參閱 Jake Archibald 撰寫的詳細說明。
Workbox 可簡化導覽預先載入作業,因為 workbox-navigation-preload
模組的 enable
方法會執行必要的功能支援檢查,並建立 activate
事件監聽器來為您啟用這項功能。
接著,使用 Workbox 以網路優先策略處理常式處理導覽要求,就能在支援瀏覽器時發揮瀏覽預先載入的好處:
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';
import {precacheAndRoute} from 'workbox-precaching';
// Precache the manifest
precacheAndRoute(self.__WB_MANIFEST);
// Enable navigation preload
navigationPreload.enable();
// Create a new navigation route that uses the Network-first, falling back to
// cache strategy for navigation requests with its own cache. This route will be
// handled by navigation preload. The NetworkOnly strategy will work as well.
const navigationRoute = new NavigationRoute(new NetworkFirst({
cacheName: 'navigations'
}));
// Register the navigation route
registerRoute(navigationRoute);
// Create a route for image, script, or style requests that use a
// stale-while-revalidate strategy. This route will be unaffected
// by navigation preload.
const staticAssetsRoute = new Route(({request}) => {
return ['image', 'script', 'style'].includes(request.destination);
}, new StaleWhileRevalidate({
cacheName: 'static-assets'
}));
// Register the route handling static assets
registerRoute(staticAssetsRoute);
啟用導覽預先載入功能後,Workbox 會回應使用 NetworkFirst
或 NetworkOnly
策略並預先載入回應的導覽要求。
如何判斷瀏覽預先載入是否正常運作?
在開發版本中,Workbox 會記錄許多其功能。如要檢查 Workbox 中是否正常運作瀏覽預先載入,請在導航要求期間,在支援的瀏覽器中開啟主控台,您會看到記錄訊息,顯示以下資訊:
根據預設,這項記錄功能不會在正式環境中顯示,因此在您將 Service Worker 部署至正式環境時,系統不會顯示這項記錄,但這是驗證導覽預先載入是否正常運作 (和其他做法) 的好方法。
自訂預先載入的回應
使用導覽預先載入功能時,您可能需要在應用程式後端自訂預先載入的回應。當服務工作處理程序從網路串流部分內容時,這就相當實用。
在這類情況下,需要知道預先載入要求是透過設為 true
預設值的 Service-Worker-Navigation-Preload
標頭傳送:
Service-Worker-Navigation-Preload: true
然後,您可以在所選應用程式後端檢查這個標頭,並依自身需求修改回應。如果標頭的預設值因任何原因造成問題,可以在視窗環境中變更。請注意,您要在伺服器中進行任何讀取這個標頭的工作,皆由您自己決定,並且不在 Workbox 的範圍內。
結論
直接使用 Navigation 預先載入並不容易,但相當值得,這麼做可以確保服務工作處理程序不會讓瀏覽器發出瀏覽要求,這是相當值得的。有了 Workbox,您無需耗費太多心力,就可以享有預先載入的導航功能。如要進一步瞭解 workbox-navigation-preload
模組,請參閱其參考說明文件。