1
头图
本文是译文,关注Web Vitals Metrics,翻译系列文章中的02篇
原文链接:First Input Delay (FID)

前言

第一印象很重要,站点也是一样。第一印象的好坏将决定用户是留存还是流失。问题是:如何才能留下好的第一印象?又如何衡量站点给用户留下的第一印象?在web网站中,用户的第一印象涉及以下几个方面:设计与视觉感染力、速度与响应快慢。用户是否喜欢网站设计很难通过API衡量,但速度和响应可以。可以用First Contentful Paint(FCP)来衡量用户访问站点时感受到的速度快慢,不过这只是一方面。用户与页面交互时,页面响应的快慢也很重要,因此我们引入FID metrics来衡量站点交互性、响应性。

1 FID的定义

衡量的是当用户第一次与站点进行如点击链接、按下按钮等操作到浏览器实际响应该操作(开始执行事件监听回调)的时间。

1.1 FID的得分标准

FID<100ms。这个标准需要覆盖站点75%的用户(后面将介绍些许差异)

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.压低请求数和传输数据的大小


xizugogo
56 声望2 粉丝

千里之行,始于足下