最佳化首次輸入延遲時間

如何更快回應使用者互動。

我點選了,但系統沒有執行任何動作!為什麼我無法與這個頁面互動?😢

首次顯示內容所需時間 (FCP) 和最大內容 繪製 (LCP) 這兩項指標可以測量內容 在網頁上視覺化呈現 (繪製) 的過程。繪製時間雖然重要,但不能充分捕捉負載 回應速度:網頁回應使用者互動的速度。

首次輸入延遲時間 (FID) 是Core Web Vitals 的指標,會擷取使用者的 每個網站的互動性和回應速度的第一印象用於評估使用者從使用者點選廣告的時間 瀏覽器實際能回應廣告請求的時間點,開始與網頁互動 互動。FID 是欄位指標, 模擬環境需要實際使用者互動才能評估 。

Fid 值為 2.5 秒,低數值超過 4.0 秒,還有需要改善的地方

為了在研究室中預測 FID 建議總封鎖時間 (TBT)。可評估的項目不同 TBT 的改善通常對應 FID 的改進。

FID 不佳的主因是大量執行 JavaScript。對 JavaScript 的剖析方式進行最佳化 在網頁上編譯並執行,會直接減少 FID 問題。

大量 JavaScript 執行

瀏覽器在主執行緒上執行 JavaScript 時,無法回應大部分的使用者輸入內容。也就是說 主執行緒忙碌時,瀏覽器無法回應使用者互動。為了改善這一點:

分散長時間執行的工作

如果您已經嘗試減少單一頁面載入的 JavaScript 數量, 將長時間執行的程式碼拆分為小型的非同步工作

長時間工作是 JavaScript 執行期間,使用者可能會藉此 您的使用者介面沒有回應。如有任何程式碼封鎖主執行緒 50 毫秒以上, 的特徵是長時間任務長時間工作是 潛在的 JavaScript 過載情形 (目前載入和執行的使用者可能不只需求)。 分隔較長的工作可以縮短網站的輸入延遲時間。

Chrome 開發人員工具中的長時間工作
Chrome 開發人員工具會在效能面板中以視覺化方式呈現長時間工作

隨著您採用程式碼分割和細分 長時間執行的工作。雖然 TBT 並非實地值,但有助於檢查最終進展 提升互動時間 (TTI) 和 FID 的效率。

將網頁最佳化,提升互動完備性

網路應用程式中,大量仰賴 FID 和 TBT 分數偏低的常見原因有很多 JavaScript:

第一方指令碼執行會延遲互動完備性

  • JavaScript 大小過載、執行時間過長與效率不彰的分塊,都會拖慢 網頁則能回應使用者輸入的內容,並影響 FID、TBT 和 TTI。漸進式載入程式碼和 功能可協助展開這項工作,並提升互動準備度。
  • 伺服器端轉譯的應用程式看似能夠在畫面上繪製像素 但請注意大型指令碼執行會阻擋使用者互動 (例如 重新補充資料。這項作業可能需要幾百毫秒 即使處理的是路徑導向的程式碼分割作業 仍會間隔數秒請考慮轉移更多邏輯 或以靜態方式產生更多內容

以下是最佳化第三方指令碼載入程序前後的待定分數 應用程式。將非必要的指令碼載入 (與執行) 移出 因為使用者能更快與網頁互動

最佳化第一方指令碼後,Lighthouse 工具中的 TBT 分數有所改善。

資料擷取可能會影響許多互動完備性

  • 等待串聯擷取作業的刊登序列 (例如元件的 JavaScript 和資料擷取作業) 可以 會影響互動延遲時間盡量減少對連鎖性資料擷取的依賴。
  • 大型內嵌資料儲存庫會排出 HTML 剖析時間,並會影響繪製和互動 指標。盡量減少用戶端上需要後處理的資料量。

第三方指令碼執行也可能會導致互動延遲

  • 許多網站都包含第三方代碼和分析功能,可維持聯播網的忙碌狀態, 讓主執行緒定期無回應,進而影響互動延遲時間。探索 隨選載入第三方程式碼 (例如,等到 都會捲動至可視區域)
  • 在某些情況下,第三方指令碼可根據優先順序和 也會延遲網頁可供互動的時間。嘗試 優先列出您認為對使用者最有價值的功能

使用網路工作站

主執行緒遭封鎖是造成輸入延遲的主要原因之一。網頁 工作站可讓您執行 JavaScript 於背景執行緒上運作將非 UI 作業移至獨立的背景工作執行緒可以減少主執行緒 進而改善 FID 的效率。

建議您根據下列程式庫,更輕鬆地在網站上使用網路工作站:

  • Comlink:可抽象的輔助程式庫 postMessage,讓你更容易使用
  • 練習:一般用途的網路工作站匯出工具
  • Workerize:將模組移至網路工作站

縮短 JavaScript 執行時間

限制網頁上的 JavaScript 數量,縮短瀏覽器所需的時間 。這樣可加快瀏覽器開始回應任何內容的速度 使用者互動狀況

如要減少您網頁上執行的 JavaScript:

  • 延後未使用的 JavaScript
  • 盡量減少未使用的 polyfill

延後未使用的 JavaScript

根據預設,所有 JavaScript 都會禁止轉譯。當瀏覽器看到連結至 外部 JavaScript 檔案時,必須暫停執行中的工作,並下載、剖析、編譯和執行 這些 JavaScript 內容因此,您應該只載入網頁所需的程式碼,或 或是回應使用者輸入的內容

Chrome 的「涵蓋範圍」分頁 開發人員工具可以指出網頁未使用 JavaScript 程度。

「涵蓋範圍」分頁。

如何減少未使用的 JavaScript:

  • 使用程式碼將套件分成多個區塊
  • 使用 asyncdefer,延遲所有非關鍵 JavaScript (包括第三方指令碼)

「程式碼分割」是將單一大型 JavaScript 組合分割成更小區塊的概念。 有條件載入的 Pod (也稱為延遲載入)。 大多數的新版瀏覽器都支援動態匯入語法, 可讓系統視需求擷取模組:

import('module.js').then((module) => {
  // Do something with the module.
});

以動態方式匯入某些使用者互動 (例如變更路線或 ) 可確保系統只有在擷取網頁 。

除了一般瀏覽器支援之外,動態匯入語法也能用於多種 有些人會將 Cloud Storage 視為檔案系統 但實際上不是

  • 如果你使用 webpack匯總、 也就是 Parcel 處理, 支援動態匯入功能
  • 用戶端架構,例如 ReactAngularVue 提供 可讓您在元件層級更輕鬆地延遲載入

除了程式碼分割之外,請一律使用 async 或 延遲不必修改密碼 重要路徑,或是不需捲動位置的內容

<script defer src="…"></script>
<script async src="…"></script>

除非有特定原因,否則所有第三方指令碼都應使用 defer 載入 或預設為 async

盡量減少未使用的 polyfill

如果您使用新型 JavaScript 語法來編寫程式碼,並參照新式瀏覽器 API,您將 必須轉碼並包含 polyfill,才能在舊版瀏覽器中運作。

如果網站加入 polyfill 和轉譯程式碼,其中一個主要的效能問題是 新版瀏覽器不需要不需要下載。為了減少 JavaScript 除了應用程式的大小之外,請盡量減少未使用的 polyfill,也可以將其使用於 打造符合需求的環境

如何最佳化網站的 polyfill 使用方式:

  • 如果使用 Babel 做為轉譯器,請使用 @babel/preset-env 表示只要包含 polyfill 所需的資訊如果是 Babel 7.9,請將 bugfixes 選項,可進一步縮小 任何不需要的 polyfill
  • 使用模組/無模組模式提供兩個不同的套件 (@babel/preset-env 和 透過 target.esmodules 支援)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

    許多環境已支援使用 Babel 編譯的許多較新的 ECMAScript 功能 以及支援 JavaScript 模組的 Pod這樣一來,您就能簡化 只有在實際需要轉譯程式碼的瀏覽器上才會使用轉譯的程式碼。

開發人員工具

有多種工具可用於評估 FID 並進行偵錯:

感謝 Philip Walton、Kayce Basques、Ilya Grigorik 和 Annie Sullivan 提供評論。