隆重推出 NoState 預先擷取

Katie Hempenius
Katie Hempenius

簡介

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

NoState Prefetch 並非 API,而是 Chrome 用來實作各種 API 和功能的機制。Resource Hints API 和 Chrome 網址列的預先載入網頁,都是使用 NoState Prefetch 實作。如果您使用的是 Chrome 63 以上版本,瀏覽器已針對 <link rel="prerender"> 等功能使用 NoState Prefetch。

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

動機

我們推出 NoState Prefetch 有兩個主要原因:

減少記憶體用量

NoState Prefetch 只會使用約 45 MiB 的記憶體。維護預先載入掃描器是 NoState 預先擷取的主要記憶體成本,且在不同用途下,這項成本仍會維持相對不變。增加擷取的大小或數量,不會對 NoState 預先擷取功能所消耗的記憶體量造成重大影響。

相較之下,預先算繪通常會耗用 100 MiB 的記憶體,且記憶體消耗量上限為 150 MiB。由於這項功能會消耗大量記憶體,因此不適合用於低階裝置 (即 RAM 容量小於 512 MB)。因此,Chrome 不會在低階裝置上執行預先算繪,而是會預先連線

方便支援新的網路平台功能

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

導入作業

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

  1. 觸發 NoStatePrefetch。

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

  2. 為 NoState Prefetch 建立新的專屬轉譯器。

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

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

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

  4. 擷取的子資源會以「IDLE」淨優先順序擷取。

    「IDLE」淨優先順序是 Chrome 中可能的最低淨優先順序。

  5. NoState 預先擷取功能擷取的所有資源,都會根據快取標頭進行快取。

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

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

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

  7. 除了更新 Cookie 儲存庫和本機 DNS 快取之外,瀏覽器不會進行任何狀態修改。這點很重要,因為這是「NoState 預先載入」中的「NoState」。

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

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

    不過,與預先算繪的網頁不同,這個網頁不會立即顯示,仍需要由瀏覽器算繪。瀏覽器不會重複使用用於 NoState 預先擷取的轉譯器,而是會使用新的轉譯器。不預先轉譯網頁可減少 NoStatePrefetch 的記憶體用量,但也會降低 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 有三個不同的統計圖表,每個用途都有一個:

  • 「NoStatePrefetch」(根據預先轉譯資源提示的使用情形統計資料)
  • “gws_NoStatePrefetch” (Google 搜尋結果網頁的使用統計資料)
  • “omnibox_NoStatePrefetch” (Chrome 網址列的使用率統計資料)