WEB 性能指标整理

Web 性能指标

对于 Web 开发人员来说,如何衡量一个 Web 页面的性能一直是一个难题。

最初使用 Time to First ByteDomContentLoadedLoad 这些衡量文档加载进度的指标(DOMContentLoaded 在 HTML 文档本解析之后触发,而 load 是在 HTML 所有相关资源被加载完成后触发。)但它们不能直接反应用户视觉体验。

为了能衡量用户视觉体验,Web 标准中定义了一些性能指标,这些性能指标被各大浏览器标准化实现,例如 First Paint 和 First Contentful Paint。还有一些由 Web 孵化器社区组(WICG)提出的性能指标,如 Largest Contentful PaintTime to InteractiveFirst Input DelayFirst CPU Idle。另外还有 Google 提出的 First Meaningful PaintSpeed Index,百度提出的 First Screen Paint

这些指标之间并不是毫无关联,而是在以用户为中心的目标中不断演进出来的,有的已经不再建议使用、有的被各种测试工具实现、有的则可以作为通用标准有各大浏览器提供的可用于在生产环境测量的 API。

一、RAIL 性能模型

用户对性能延迟的看法

RAILResponse, Animation, Idle, 和 Load 的首字母缩写, 是一种由 Google Chrome 团队于 2015 年提出的性能模型, 用于提升浏览器内的用户体验和性能。RAIL 模型的理念是"以用户为中心.

这个名字的由来是四个英文单词的首字母:

  • 响应Response):应该尽可能快速的响应用户, 应该在 100ms 以内响应用户输入。

  • 为了确保在 100 毫秒内产生可见响应,需要在 50 毫秒内处理用户输入事件。

  • 例如点击按钮、切换表单控件或启动动画。

  • 动画Animation):从技术上来说,在展示动画的时候,每一帧应该以 16ms 进行渲染(1秒60帧,一帧16.6ms),这样可以保持动画效果的一致性。但是浏览器需要大约 6 毫秒来渲染一帧,所以目标上得在10 毫秒或更短的时间内生成动画的每一帧 。

    • 例如进入和退出,滚动效果,平移地图或捏合缩放。
  • 空闲Idle):当执行长任务时,应该把主线程的任务划分到执行时间小于 50ms 的片段中去,这样可以释放线程以进行用户交互。

    • 例如React在低版本复杂组件渲染卡顿使用Fible解决,其实就是利用了这个空闲时间。
  • 加载Load):根据用户的设备和网络能力优化相关的快速加载性能。目前对于网速快的电脑设备,应该在小于 1s-2s 的时间内加载完成你的网站,并可以进行用户交互。对于首次加载,在使用速度较慢 3G 连接的中端移动设备上,理想的目标是在 5 秒或更短的时间内实现可交互。

    • 例如,通过快速 Wi-Fi 连接,在功能强大的台式机上加载站点时,通常只需不到 1 秒时间,用户已经习以为常。通过速度较慢的 3G 网络连接,在移动设备上加载站点则需要更长的时间,因此,移动用户通常会更有耐心。在移动设备上,5 秒钟内完成加载是更现实的目标。

二、基于用户体验的性能指标

LCP最大内容绘制 (Largest Contentful Paint)

LCP(Largest Contentful Paint)最大内容绘制,可视区域最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户可见时间。

LCP 考虑的元素:

  • img 元素

  • image元素内的 svg元素

  • video 元素(封面图)

  • 通过 url() 函数加载背景图片的元素

  • 包含文本节点或其他内联级文本元素子级的块级元素

为了提供良好的用户体验,网站应力争使用 2.5 秒或更短的"最大内容绘画" 。

以下是一些示例:

在以上两个时间轴中,最大的元素随内容加载而变化。在第一个示例中,新内容被添加到DOM中,并且更改了最大的元素。在第二个示例中,布局发生更改,以前最大的内容从视口中删除。

通常情况下,延迟加载的内容要比页面上已有的内容大,但不一定是这种情况。接下来的两个示例显示了在页面完全加载之前发生的最大内容绘画。

在这个示例中,Instagram 徽标相对较早地加载,即使逐渐显示其他内容,它仍然是最大的元素。

在 Instagram 时间轴的第一帧中,您可能会注意到相机徽标周围没有绿色框。那是因为它是一个 svg 元素,并且 svg元素当前不被视为 LCP 候选对象。

在 Google 搜索结果页面示例中,最大的元素是一段文本,该文本在任何图像或徽标加载完成之前显示。由于所有单个图像均小于此段,因此在整个加载过程中,它始终是最大的元素。

速度指标

LCP时间(秒) 速度
0-2.5 绿色(快速)
0-4 橙色(中等)
超过4 红色(慢)

如何改进 LCP

LCP 主要受四个因素影响:

  • 缓慢的服务器响应速度

  • JavaScript 和 CSS 渲染阻塞

  • 资源加载时间

  • 客户端渲染

优化方案

FID 首次输入延迟 (First Input Delay)

FID(First Input Delay)首次输入延迟,从用户第一次与页面交互(例如单击链接、点击按钮等)到浏览器实际能够响应该交互的时间。

输入延迟是因为浏览器的主线程正忙于做其他事情,所以不能响应用户。发生这种情况的一个常见原因是浏览器正忙于解析和执行应用程序加载的大量计算的 JavaScript。

第一次输入延迟通常发生在第一次内容绘制(FCP)和可持续交互时间(TTI)之间,因为页面已经呈现了一些内容,但还不能可靠地交互。

如上图所示,浏览器接收到用户输入操作时,主线程正在忙于执行一个耗时比较长的任务,只有当这个任务执行完成后,浏览器才能响应用户的输入操作。它必须等待的时间就此页面上该用户的 FID 值。

例如,以下所有 HTML 元素都需要在响应用户交互之前等待主线程上正在进行的任务完成:

  • 文本输入框,复选框和单选按钮(input,textarea)
  • 选择下拉菜单(select)
  • 链接(a)

速度指标

优化方案

CLS 累积布局偏移 (Cumulative Layout Shift)

Cumulative Layout Shift(CLS)累计布局偏移,CLS 会测量在页面整个生命周期中发生的每个意外的布局移位的所有单独布局移位分数的总和,它是一种保证页面的视觉稳定性从而提升用户体验的指标方案。

您是否曾经在页面上突然发生变化时在没有警告的情况下,文字移动了,并且您失去了位置。甚至更糟:您将要点击一个链接或一个按钮,但是在手指落下的瞬间,链接移动了,您最终单击了其他东西!

页面内容的意外移动通常是由于异步加载资源或将 DOM 元素动态添加到现有内容上方的页面而发生的。罪魁祸首可能是尺寸未知的图像或视频,呈现比其后备更大或更小的字体,或者是动态调整自身大小的第三方广告或小部件。

速度指标

CLS时间(秒) 速度
0-0.1 绿色(快速)
0.1-0,25 橙色(中等)
超过0,25 红色(慢)

优化方案

FCP首次内容绘制 (First Contentful Paint)

FCP(First Contentful Paint)首次内容绘制浏览器首次绘制来自 DOM 的内容的时间 ,内容必须是文本图片(包含背景图)、非白色的 canvas 或 SVG,也包括带有正在加载中的 Web 字体的文本

这是用户第一次开始看到页面内容,但仅仅有内容,并不意味着它是有用的内容(例如 Header、导航栏等),也不意味着有用户要消费的内容。在第二张图的时候FCP就已经出来来了,它指的是html中的dom渲染完成之后的时间,后续动态创建的不管

速度指标

FCP时间(秒) 速度 (HTTP存档百分位数)
0-2 绿色(快速) 75--100
2-4 橙色(中等) 50--74
超过4 红色(慢) 0--49

优化方案

TTI 可交互时间 (Time to Interactive)

表示网页第一次 完全达到可交互状态 的时间点,浏览器已经可以持续性的响应用户的输入。完全达到可交互状态的时间点是在最后一个长任务(Long Task)完成的时间, 并且在随后的 5 秒内网络和主线程是空闲的。

速度指标

LCP时间(秒) 速度
0-2.5 绿色(快速)
0-4 橙色(中等)
超过4 红色(慢)

优化方案

TBT 总阻塞时间 (Total Blocking Time)

Total Block Time(TBT)总阻塞时间,度量了 FCP 和 TTI 之间的总时间,在该时间范围内,主线程被阻塞足够长的时间以防止输入响应。

只要存在长任务,该主线程就会被视为"阻塞",该任务在主线程上运行超过50毫秒(ms)。我们说主线程"被阻止"是因为浏览器无法中断正在进行的任务。因此,如果用户确实在较长的任务中间与页面进行交互,则浏览器必须等待任务完成才能响应。

如果任务足够长(例如,超过50毫秒的任何时间),则用户很可能会注意到延迟并感觉页面缓慢或过时。

给定的长任务的阻止时间是其持续时间超过50毫秒。页面的总阻塞时间是FCP和TTI之间发生的每个长任务的阻塞时间的总和。

速度指标

TBT时间(秒) 速度
0-300 绿色(快速)
300-600 橙色(中等)
超过600 红色(慢)

优化方案

FPS 每秒绘制帧数(Frames Per Second)

帧率是视频设备产生图像(或帧)的速率,用每秒可以重新绘制的帧数(Frames Per Second,FPS)表示。

重新绘制可能需要重新计算样式、布局和绘制,如果每帧绘制到屏幕的时间在 16.7 ms 以上,每秒绘制的帧数就会小于 60 帧,人眼就能感受到页面出现卡顿,所以 FPS 是衡量应用流畅度的一个非常重要的指标,60fps 是页面流畅的目标,可以为每次绘制提供 16.7ms 的时间预算。

既然帧率与页面重新绘制有关,那我们可以思考两个问题:

哪些情况下会触发重新绘制?

FPS 在电影和游戏中最为常见,但现在被广泛用作衡量网站和网络应用程序性能的指标。

在 Web 性能中,FPS 最常用于衡量动画的性能:如果 FPS 太低,动画会卡顿。

FPS 也可以作为用户与页面交互时页面响应性的一般度量。例如,如果将鼠标移到某个页面元素上会触发执行 JavaScript 来更新页面,这可能会触发回流和重绘,这需要在帧中完成,如果浏览器处理帧的时间过长,将会出现卡顿现象。

再例如,如果在滚动页面时会触发很多复杂的页面更新,并且浏览器无法保持可接受的帧率,那么滚动页面时会显得迟缓或卡顿。

如何降低重新绘制的时间?

重新绘制到屏幕可能需要从构建 DOM 树开始、重新计算样式、布局、绘制等,我们需要尽可能的避免触发这些流程,例如使用 CSS 修改 opacity 属性就不会触发重新布局,可以减少绘制时间。

所以在实现动画时,建议使用性能成本低的 CSS 属性,而不要使用 JavaScript 设置元素。

TTFB 接收第一字节的时间(Time to First Byte)

浏览器从请求页面开始到接收第一字节的时间,这个时间段内包括 DNS 查找、TCP 连接和 SSL 连接。

SI 页面内容填充速度(Speed Index)

这是一个表示页面可视区域中内容的填充速度的指标,可以通过计算页面可见区域内容显示的平均时间来衡量。

测量方式

首先在浏览器中捕获页面加载的视频,然后对每 100 毫秒间隔的页面截图计算页面填充的百分比,可以得到这样一个曲线(纵轴是页面可视区域内容填充完成度,横轴是时间)。

图中的 Example 1 和 Example 2 都是在 10s 时页面填充完成,但 Example 1 在 2s 是就已经填充了 80% 的内容,而 Example 2 在 8s 时才填充 80%。

图中阴影部分的面积(即时间-内容填充百分比曲线以上部分)的大小即可表示可视区域内页面内容的填充速度,面积越小,填充速度越快。

如果用时间来衡量,可以这样计算,以此来表示页面可见区域内容显示的平均时间。

Plain Text

Example 1:Speed Index = (80% * 2) + (20% * 10)= 3.6

Example 2:Speed Index = (80% * 8) + (20% * 10)= 8.4

这个平均时间可以用来比较首屏内容完整呈现给用户的性能体验,但它计算的不是首屏内容完整呈现这一时刻,不能算是一个用时间来度量的指标。

三、Web Vitals

Google 在 2020 年 5 月 5 日提出了新的用户体验量化方式 Web Vitals 来衡量网站的用户体验,并将这些衡量结果用作其排名算法的一部分。过去要衡量一个网站的好坏,需要使用的指标太多了。在 Web Vitals 中,Google 确定了三个主要衡量指标:

  • 加载性能(LCP) --- 显示最大内容元素所需时间

  • 交互性(FID) --- 首次输入延迟时间

  • 视觉稳定性(CLS) --- 累积布局配置偏移

这三个指标已经经过了一段时间的验证,如 LCP 在 WICG 已经孵化至少1年以上,FID 在 Google Chrome Labs 上已经实施2年以上,LCP 和 CLS (相关布局不稳定 API)已于前几年入了 W3C 草拟标准

测量 Web Vitals

  • 性能测试工具,比如 Lighthouse

  • 使用 web-vitals

  • 使用浏览器插件 Web Vitals

优化 Web Vitals

四、其它性能指标

  • 重定向次数:performance.navigation.redirectCount
  • 重定向耗时: redirectEnd - redirectStart
  • DNS 解析耗时: domainLookupEnd - domainLookupStart
  • TCP 连接耗时: connectEnd - connectStart
  • SSL 安全连接耗时: connectEnd - secureConnectionStart
  • 网络请求耗时 (TTFB): responseStart - requestStart
  • 数据传输耗时: responseEnd - responseStart
  • DOM 解析耗时: domInteractive - responseEnd
  • 资源加载耗时: loadEventStart - domContentLoadedEventEnd
  • 首包时间: responseStart - domainLookupStart
  • 白屏时间: responseEnd - fetchStart
  • 首次可交互时间: domInteractive - fetchStart
  • DOM Ready 时间: domContentLoadEventEnd - fetchStart
  • 页面完全加载时间: loadEventStart - fetchStart
  • http 头部大小: transferSize - encodedBodySize
  • Time to First Byte(TTFB):浏览器从请求页面开始到接收第一字节的时间,这个时间段内包括 DNS 查找、TCP 连接和 SSL 连接。
  • Frames Per Second(FPS)
相关推荐
学不会•42 分钟前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
EasyNTS2 小时前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年5 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder6 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript