隆重推出 NoState 預先擷取

Katie Hempenius
Katie Hempenius

簡介

NoState Prefetch 是 Chrome 中的一項新機制,除了已淘汰的預先算繪程序外,還能用來提供 <link rel="prerender"> 等功能。和預先轉譯一樣,系統會預先擷取資源,但與預先算繪不同,前者不會預先執行 JavaScript,也不會預先轉譯網頁的任何部分。NoState 預先擷取的目標是使用比預先算繪更少的記憶體,同時也能縮短網頁載入時間。

NoState Prefetch 並非 API,而是 Chrome 用來實作各種 API 和功能的機制。Resource Hints API 以及 Chrome 網址列預先擷取網頁,兩者皆是使用 NoState Prefetch 實作。如果您使用的是 Chrome 63 以上版本,表示瀏覽器已啟用 NoState 預先擷取功能,例如 <link rel="prerender">

本文將說明 NoStatePrefetch 的運作方式、導入的動機,以及使用 Chrome 直方圖查看用量統計資料的操作說明。

動機

導入 NoState 預先擷取的主要動機有兩大動機:

降低記憶體用量

NoState 預先擷取只會使用約 45 MiB 的記憶體。維護預先載入掃描器是 NoState Prefetch 的主要記憶體費用,因此此費用在不同使用情境下會保持相對穩定。增加擷取大小或數量,對於 NoState Prefetch 耗用的記憶體容量沒有重大影響。

相較之下,預先算繪通常會耗用 100 MiB 的記憶體和記憶體,上限為 150 MiB。這種記憶體消耗量偏高,因此不適合低階 (即小於 512 MB 的 RAM) 裝置。因此,Chrome 不會在低階裝置上進行預先算繪,而會改為預先連線

協助支援新的網路平台功能

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

導入作業

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

  1. 觸發 NoStatePrefetch。

    預先算繪資源提示 (例如 <link rel="prerender">) 和部分 Chrome 功能只要符合以下兩個條件,就會觸發 NoState 預先擷取:a) 使用者並非使用低階裝置,以及 b) 使用者並非使用行動網路。

  2. 系統會為 NoState 預先擷取作業建立新的專屬轉譯器。

    在 Chrome 中,「轉譯器」是一項程序,負責擷取 HTML 文件、剖析文件、建構其轉譯樹狀結構,以及將結果繪製在畫面上。Chrome 中的每個分頁和每個 NoState 預先擷取程序都有專屬的轉譯器。這有助於盡量減少問題發生 (例如分頁異常終止) 的影響,並防止惡意程式碼存取系統的其他分頁或系統其他部分。

  3. 透過 NoState 預先擷取功能載入的資源會擷取。接著,HTMLPreloadScanner 會掃描這項資源,找出需要擷取的子資源。如果主要資源或其任何子資源有已註冊的 Service Worker,這些要求就會透過適當的服務工作處理程序傳送。

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

  4. 擷取的子資源會以「IDLE」網路優先順序進行擷取。

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

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

    NoState 預先擷取會快取除含有 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 預先擷取中斷的地方繼續載入網頁。瀏覽器仍需要擷取資源,但如果未啟動 NoState 預先擷取,則瀏覽器會需要擷取資源,而不需用到太多資源。

對網頁分析的影響

使用 NoState Prefetch 載入的網頁視工具是在用戶端還是伺服器端收集資料而定,而網站分析工具註冊的時間也會略有不同。

用戶端分析指令碼會在使用者看到網頁時記錄一次網頁瀏覽。這些指令碼仰賴 JavaScript 執行作業,而 NoState Prefetch 不會執行任何 JavaScript。

處理要求時,伺服器端分析工具會記錄指標。如果是透過 NoState Prefetch 載入的資源,處理要求到用戶端實際使用回應之間可能會有很長的時間差距 (如果會用到回應的話)。自 Chrome 69 版起,NoState Prefetch 會在所有要求中加入 Purpose: Prefetch 標頭,藉此與一般瀏覽方式區分。

一探究竟

NoStatePrefetch 已於 2017 年 12 月透過 Chrome 63 推出。目前用於:

  • 實作 prerender 資源提示
  • 擷取 Google 搜尋結果中的第一筆搜尋結果
  • 擷取 Chrome 網址列預測可能造訪的網頁

您可以透過 Chrome 內部功能,查看自己使用 NoStatePrefetch 的情況。

如要查看已使用 NoState 預先擷取功能載入的網站清單,請前往 chrome://net-internals/#prerender

如要查看 NoState Prefetch 使用情形的統計資料,請前往 chrome://histograms 並搜尋「NoStatePrefetch」。以下是三種不同的 NoState 預先擷取直方圖,分別用於 NoState 預先擷取用途:

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