前端性能指標:First Input Delay

本文是譯文,關注Web Vitals Metrics,翻譯系列文章中的02篇
原文連接: First Input Delay (FID)

前言

第一印象很重要,站點也是同樣。第一印象的好壞將決定用戶是留存仍是流失。問題是:如何才能留下好的第一印象?又如何衡量站點給用戶留下的第一印象?在web網站中,用戶的第一印象涉及如下幾個方面:設計與視覺感染力、速度與響應快慢。用戶是否喜歡網站設計很難經過API衡量,但速度和響應能夠。能夠用First Contentful Paint(FCP)來衡量用戶訪問站點時感覺到的速度快慢,不過這只是一方面。用戶與頁面交互時,頁面響應的快慢也很重要,所以咱們引入FID metrics來衡量站點交互性、響應性。javascript

1 FID的定義

衡量的是當用戶第一次與站點進行如點擊連接、按下按鈕等操做到瀏覽器實際響應該操做(開始執行事件監聽回調)的時間。
java

1.1 FID的得分標準

FID<100ms。這個標準須要覆蓋站點75%的用戶(後面將介紹些許差別)web

1.2 深刻介紹FID的細節

寫事件處理代碼的程序猿們常認爲只要事件發生了處理代碼就會當即執行。但對於用戶們來講感到的卻截然相反:頁面加載已經完畢,嘗試操做它但卻沒有任何反應。多麼讓人失望!
ID(input delay)一般發生在瀏覽器主線程忙於作其它的事沒法響應用戶操做。主線程忙於解析、執行web應用中加載的較大的JavaScript文件。解析、執行JavaScript時,主線程又會去被告知處理其它事情,所以沒法執行事件監聽。
給出web頁面加載資源時,主線程執行示意圖,如圖1:

能夠看到圖中灰色塊演示的是頁面發起網絡請求5個資源(CSS或者JS),而後,當每一個資源下載完成後,主線程就開始處理。形成的結果是,如黃色圖塊展現的那樣,主線程是階段性忙碌的。瀏覽器

FID發生在FCP以後,TTI(Time to Interactive)以前。這個階段頁面上已經渲染了部份內容但又沒有準備好可交互。如圖2:

如圖所知,FCP和TTI之間時間較長,若是在這個時間段裏用戶嘗試與頁面進行交互,從瀏覽器收到click事件到主線程得空處理它之間存在延遲。 由於input事件發生在瀏覽器正在執行任務時,要等它完成後才能響應input事件。等待時長即爲FID值。如圖3:
網絡


介紹完FID發生的階段,下面經過五個問題,介紹FID設計的細節。異步

(1)沒有添加用戶行爲監聽有什麼影響?

FID衡量的是從接收到input事件到主線程變得空閒之間的時間差。因此有無綁定事件監聽並不影響FID。實際上,不少用戶行爲並不須要綁定事件監聽處理,但卻必定須要主線程在空閒時去執行。標籤如<input>, <textarea>,<raido>,<select>,<a>都須要等待主線程中正在執行的任務完成以後才能響應用戶的交互行爲。工具

(2)爲何只考慮第一次輸入?

只考慮第一次源於前述的第一印象很重要;另外,加載階段的交互性問題是交互性問題的重災區;加載時、加載後的ID問題的解決辦法不互通,須要分開討論。性能

(3)哪些纔算是輸入?

FID是加載階段衡量頁面響應性的指標,它只關注input事件和離散行爲如:點擊、觸摸、按鍵事件。其它諸如滾動、縮放是連續行爲,在性能方面具備大相徑庭的要求(也正所以瀏覽器一般將它們運行在單獨的線程中以掩蓋其延遲執行)。從另一方面來講,根據RAIL性能模型,FID屬於R,而滾動、縮放更多的是A,須要分開討論其性能。優化

(4)若是用戶不和站點交互怎麼辦?

用戶訪問站點時不必定會跟頁面交互,也不是全部的交互事件都跟FID有關係(如前所述)。另外,一些用戶的首次交互發生在主線程忙碌時,而另外的又剛好落入主線程空閒區間。這就意味着,同一站點,有些用戶得不到FID值,有些FID值低,有些又很高。從這一方面來看,分析FID跟分析其餘指標稍有不一樣(見後文)。網站

(5)爲何只考慮延遲時間?

FID只是延遲的那段時間,既不包含事件處理的耗時,也不考慮事件處理後瀏覽器更新UI的時間。這兩個時間的確也重要,也能影響用戶體驗。之因此不包括它們是由於,若是歸入到FID之中,可能會致使程序猿們想出一些規避的辦法,這將使用戶體驗變差。規避的辦法:把事件處理邏輯包裹在異步回調(setTimeout() 和 requestAnimationFrame())之中,能夠分離事件處理回調和事件相關的任務。從指標上來看是提高了,但從用戶感知方面,實際上響應變慢。

2 如何衡量FID

因爲依賴用戶與站點進行交互,FID只能在現場階段衡量。

TBT能夠在Lab階段衡量,FID又與TBT相關聯,在Lab階段改進TBT也有助於FID的提高。

現場工具

Chrome User Experience Report
PageSpeed Insights
Search Console (Core Web Vitals report)
web-vitals JavaScript library

JavaScript API

(1)利用Event Timing API(W3C標準的一個提案)和PerformanceObserver

使用舉例:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const delay = entry.processingStart - entry.startTime;
    console.log('FID candidate:', delay, entry);
  }
}).observe({type: 'first-input', buffered: true});

這裏是簡單介紹delay是如何計算的,並說明了這個計算結果只是FID的候選人,並非全部的delay結果都對FID的測量有用。而後介紹具體分發first-input Entry的幾個特殊狀況,好比:tab後臺頁面中分發的first-input、first-input發生前頁面加載時也會分發的first-input Entry會在計算FID時被忽略。cache中得到的頁面、iframe中頁面不會分發。
須要考慮的細節不少,因此開發者們可使用JavaScript庫web-vitals來測量FID,庫的做用就是爲你(儘量的)屏蔽這些細節差別。

(2)web-vitals庫

import {getFID} from 'web-vitals';
getFID(console.log);

3 分析和報告FID數據

如第1節所述,FID值存在不定因素,因此須要關注數據的分佈,也須要提升指標達標用戶所佔的比例。相比其餘的核心指標要求的75%用戶,FID最好要知足95-99%。

4 如何改進FID

咱們建議利用Lighthouse進行性能分析,關注其中的優化建議;另外,因爲FID是現場指標,而Lighthouse是Lab工具,所以須要提高Lab指標TBT。更多的改進辦法見以下連接:

1.爲主線程「減壓」
2.減小JavaScript執行耗時
3.削弱第三方代碼的影響
4.壓低請求數和傳輸數據的大小

相關文章
相關標籤/搜索