隆重推出 NoState 預先擷取

Katie Hempenius
Katie Hempenius

發布日期:2018 年 7 月 20 日

簡介

無狀態預先擷取是 Chrome 的新機制,可替代已淘汰的預先轉譯程序,用於支援 <link rel="prerender"> 等功能。與預先算繪一樣,預先擷取會預先擷取資源,但與預先算繪不同的是,預先擷取不會執行 JavaScript,也不會預先算繪網頁的任何部分。NoState Prefetch 的目標是減少記憶體用量,同時縮短網頁載入時間。

NoState Prefetch 並非 API,而是 Chrome 用來實作各種 API 和功能的機制。資源提示 API 和 Chrome 網址列預先擷取的網頁,都是使用 NoState Prefetch 實作。如果您使用 Chrome 63 以上版本,瀏覽器已為<link rel="prerender">等功能採用 NoState Prefetch。

本文將說明 NoStatePrefetch 的運作方式、推出這項功能的動機,以及如何使用 Chrome 的直方圖查看相關統計資料。

動機

我們推出 NoState Prefetch 的主要動機有兩個:

減少記憶體用量

NoState Prefetch 只會使用約 45 MiB 的記憶體。維護預先載入掃描器是 NoState Prefetch 的主要記憶體支出,且不同用途的成本相對穩定。增加擷取的大小或數量,對 NoState Prefetch 消耗的記憶體量不會有顯著影響。

相較之下,預先算繪通常會耗用 100 MiB 的記憶體,且記憶體消耗量上限為 150 MiB。這類高記憶體用量不適合低階裝置 (即 RAM <= 512MB)。因此,Chrome 不會在低階裝置上預先算繪,而是會預先連線

支援新的網頁平台功能

預先算繪時,不應發生任何面向使用者的動作 (例如播放音樂或影片),或具狀態的動作 (例如變更工作階段或本機儲存空間)。不過,在網頁算繪期間,要防止發生這些動作可能很困難且複雜。NoState Prefetch 只會預先擷取資源,不會執行程式碼或轉譯網頁。這樣一來,就能更輕鬆地防止發生面向使用者和有狀態的動作。

導入作業

下列步驟說明 NoState Prefetch 的運作方式。

  1. 系統會觸發 NoStatePrefetch。

    如果符合下列兩項條件,預先算繪資源提示 (即 <link rel="prerender">) 和部分 Chrome 功能會觸發 NoState Prefetch:a) 使用者並非使用低階裝置,且 b) 使用者並非使用行動網路。

  2. 系統會為無狀態預先擷取功能建立新的專屬算繪器。

    在 Chrome 中,「轉譯器」是負責擷取及剖析 HTML 文件、建構轉譯樹狀結構,並將結果繪製到螢幕上的程序。Chrome 中的每個分頁,以及每個 NoState Prefetch 程序,都有自己的算繪器,可提供隔離功能。這有助於將出錯 (例如分頁當機) 的影響降至最低,並防止惡意程式碼存取其他分頁或其他系統部分。

  3. 系統會擷取透過 NoState Prefetch 載入的資源。HTMLPreloadScanner 接著會掃描這項資源,找出需要擷取的任何子資源。如果主要資源或任何子資源已註冊服務工作人員,這些要求會透過適當的服務工作人員傳送。

    NoState Prefetch 僅支援 GET HTTP 方法,不會擷取需要使用其他 HTTP 方法的任何子資源。此外,系統不會擷取任何需要使用者操作的資源 (例如驗證彈出式視窗、SSL 用戶端憑證或手動覆寫)。

  4. 系統會以「IDLE」網路優先順序擷取子資源。

    「IDLE」網路優先順序是 Chrome 中最低的網路優先順序。

  5. NoState Prefetch 擷取的所有資源都會根據快取標頭進行快取。

    NoState Prefetch 會快取所有資源,但具有 no-store Cache-Control 標頭的資源除外。如有 Vary 回應標頭、no-cache Cache-Control 標頭,或資源已超過 5 分鐘,系統會在資源使用前重新驗證。

  6. 所有子資源載入完畢後,系統會終止轉譯器。

    如果子資源逾時,轉譯器會在 30 秒後終止。

  7. 除了更新 Cookie 儲存區和本機 DNS 快取之外,瀏覽器不會進行任何狀態修改。 請務必注意這一點,因為這是「NoState Prefetch」中的「NoState」。

    在「正常」網頁載入程序的這個階段,瀏覽器可能會執行會修改瀏覽器狀態的動作,例如執行 JavaScript、變動 sessionStoragelocalStorage、播放音樂或影片、使用 History API,或是提示使用者。NoState Prefetch 中唯一發生的狀態修改,是回應抵達時更新 DNS 快取,以及回應包含 Set-Cookie 標頭時更新 Cookie 儲存空間。

  8. 需要資源時,系統會將資源載入瀏覽器視窗。

    不過,與預先算繪的網頁不同,網頁不會立即顯示,仍需由瀏覽器算繪。瀏覽器不會重複使用 NoState Prefetch 所用的算繪器,而是會使用新的算繪器。不預先算繪網頁可減少 NoStatePrefetch 的記憶體用量,但對網頁載入時間的影響也會隨之降低。

    如果網頁有 Service Worker,這次載入網頁時會再次經過 Service Worker。

    如果需要網頁時,NoState Prefetch 尚未完成擷取子資源,瀏覽器會從 NoState Prefetch 停止的位置繼續載入網頁。瀏覽器仍需擷取資源,但數量不會像未啟動 NoState Prefetch 時那麼多。

對網站分析的影響

網頁分析工具註冊使用 NoState Prefetch 載入的網頁時,會稍微延遲,具體時間取決於工具是在用戶端還是伺服器端收集資料。

當網頁向使用者顯示時,用戶端 Analytics 指令碼會記錄網頁瀏覽。這些指令碼會執行 JavaScript,但 NoState Prefetch 不會執行任何 JavaScript。

伺服器端分析工具會在處理要求時註冊指標。透過 NoState Prefetch 載入的資源,在要求處理完畢與用戶端實際使用回應 (如果會使用) 之間,可能會出現明顯的時間差。自 Chrome 69 起,NoState Prefetch 會在所有要求中加入 Purpose: Prefetch 標頭,以便與一般瀏覽區別。

一探究竟

NoStatePrefetch 已於 2017 年 12 月在 Chrome 63 中發布。目前用於:

  • 導入 prerender 資源提示
  • 擷取 Google 搜尋結果中的第一個結果
  • 擷取 Chrome 網址列預測您接下來可能造訪的網頁

您可以使用 Chrome 內部工具,查看 NoStatePrefetch 的使用情形。

如要查看已透過 NoState Prefetch 載入的網站清單,請前往 chrome://net-internals/#prerender

如要查看 NoState Prefetch 的使用統計資料,請前往 chrome://histograms 並搜尋「NoStatePrefetch」。NoState Prefetch 有三種不同的直方圖,分別對應 NoState Prefetch 的三種用途:

  • 「NoStatePrefetch」(預先算繪資源提示的使用統計資料)
  • 「gws_NoStatePrefetch」(Google 搜尋結果網頁的使用統計資料)
  • 「omnibox_NoStatePrefetch」(Chrome 網址列的使用統計資料)