type
status
date
slug
summary
tags
category
icon
password

1 网页性能优化指标

1.1 测试工具

公网上的网页进行FCP测试的工具:
  • PSI:会针对网页在移动设备和桌面设备上的用户体验生成报告,并就如何改进网页提出建议
在本地调试的时候可以使用 DevToolslighthouse来查看
 

1.2 核心 Web 指标

适用于所有网页的 Web 指标子集,每位网站所有者都应该测量这些指标,并且这些指标还将显示在所有 Google 工具中
LCP ➡️Largest Contentful Paint
  • 最大内容渲染时间
  • 从页面开始加载到视窗内最大内容绘制的所需时间,测量加载性能
CLS ➡️Cumulative Layout Shift
  • 累计布局位移
  • 比较单个元素在帧与帧之间的位置偏移,测量视觉稳定性
FID ➡️ First Input Delay
  • 首次输入延迟
  • 测量交互性
FCP ➡️First Contentful Paint
不包含核心 Web 指标中,但是以下PSI指标和lighthouse指标都包含。因为只会捕获加载体验最开始的部分,如果某个页面显示的是一段启动画面或加载指示,那么这些时刻与用户的关联性并不大。
  • 首次内容绘制
  • 是浏览器在您的页面上呈现第一个DOM元素的时间。这包括图像、画布元素(非白色)或文本。通俗地说,FCP是指用户可以看到页面的某些部分发生变化。
 

1.3 PSI工具指标

除核心指标之外还包括
INP ➡️ Interaction to Next Paint
INP 与首次输入延迟 (FID) 的不同:INP 考虑所有页面交互,而FID仅考虑第一次交互。它还仅测量第一次交互的输入延迟,而不是运行事件处理程序所需的时间或呈现下一帧的延迟。
  • 下次绘制交互
  • 将于2024 年 3 月取代首次输入延迟 (FID)。通过观察用户访问页面的整个生命周期中发生的所有单击、敲击和键盘交互的延迟来评估页面对用户交互的整体响应能力。低 INP 意味着页面始终能够快速响应所有(或绝大多数)用户交互。
TTFB(experimental)➡️ Time to First Byte
  • 首字节时间

1.4 谷歌控制台lighthouse指标

除核心指标之外还包括
SI ➡️Speed Index
  • 速度指数
  • 反映网页内容填充的速度
TBT ➡️Total Blocking Time
  • 阻塞总时间
  • 反映用户的交互是否能及时响应
 

2 具体介绍与优化方案

2.1 LCP

2.1.1 什么是LCP

LCP最大内容绘制会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。

2.1.2 最大内容绘制考量的元素

  • <img>元素
  • 内嵌在<svg>元素内的<image>元素
  • <video>元素(使用封面图像)
  • 通过url()函数(而非使用CSS 渐变)加载的带有背景图像的元素
  • 包含文本节点或其他行内级文本元素子元素的块级元素。

2.1.3 元素大小的计算方式

用户在视口中可见的元素的大小。如果元素延伸到视口之外,或者任何元素被剪裁或具有不可见的溢出,则这些部分不会计入元素的大小。
1️⃣如果图片缩放,尺寸以较小者为准 2️⃣文本元素,仅考虑其文本节点的大小 3️⃣所有元素,不考虑通过 CSS 应用的任何边距、填充或边框 4️⃣<svg>元素目前不被视为 LCP 候选者 5️⃣使用background-image插入的背景图不会被视为最大内容绘制元素 💡如果当前最大内容元素的元素从视口中删除(甚至从 DOM 中删除),它将仍然是最大内容元素,除非渲染更大的元素。
💡对元素大小或位置的更改不会生成新的 LCP 候选对象,只有元素在可视区域内的初始大小和位置会被纳入考量范围。

2.1.4 LCP分发和报告最大内容的过程

例如,在一个带有文本和首图的网页上,在界面上的较大图片元素尚未“渲染完成”的时候,较小的先渲染完成的文本元素将会被视为第一个最大内容绘制元素,浏览器此期间会分发一个largest-contentful-paint条目给这个文本元素,用于识别最大内容元素。随后,一旦首图完成加载,浏览器就会分发第二个largest-contentful-paint条目。如果这个界面还有其他元素,有任意一个新元素大于先前的最大内容元素,则浏览器还将报告一个新的PerformanceEntry条目。

2.1.5 最大内容绘制元素频繁变化的影响

计算和分发新性能条目的性能开销较高时:
1️⃣会导致用户等待时间增加,出现例如图片加载不完整或动画无法流畅播放的情况
2️⃣会导致交互延迟,用户点击按钮或执行其他操作时的响应时间会增加
3️⃣页面加载期间用户无法操作,对搜索引擎优化(SEO)有一定影响

2.1.6 示例

最大内容元素从顶部的文本元素,变更为渲染完成之后的图片元素,LCP发生变化
最大内容元素从顶部的文本元素,变更为渲染完成之后的图片元素,LCP发生变化
最大内容元素是一串文本元素,随着布局的改变被从可视区域中被移除,但是依旧是最大内容元素,直到被更大的图片元素取代,LCP发生变化
最大内容元素是一串文本元素,随着布局的改变被从可视区域中被移除,但是依旧是最大内容元素,直到被更大的图片元素取代,LCP发生变化
延迟加载方案
第一张图为svg元素不会被算作最大内容元素,第二张图的图片在渲染中状态,不能计算。随着图片渲染完成,图片元素成为第一次的最大内容元素,之后的元素都在图片之后渲染完成,但都没有图片元素大,所以图片是依旧是界面内的最大内容元素
第一张图为svg元素不会被算作最大内容元素,第二张图的图片在渲染中状态,不能计算。随着图片渲染完成,图片元素成为第一次的最大内容元素,之后的元素都在图片之后渲染完成,但都没有图片元素大,所以图片是依旧是界面内的最大内容元素
当用户与页面进行交互(通过轻触、滚动或按键)时,浏览器将立刻停止报告新条目,因为用户交互通常会改变用户可见的内容(滚动操作时尤其如此)
所以在进行搜索交互之后,最大内容元素为图二这段文本,文本在所有图像或标志完成加载之前就显示了出来。由于所有单个图像都小于这段文字,因此这段文字在整个加载过程中始终是最大元素。
当用户与页面进行交互(通过轻触、滚动或按键)时,浏览器将立刻停止报告新条目,因为用户交互通常会改变用户可见的内容(滚动操作时尤其如此) 所以在进行搜索交互之后,最大内容元素为图二这段文本,文本在所有图像或标志完成加载之前就显示了出来。由于所有单个图像都小于这段文字,因此这段文字在整个加载过程中始终是最大元素。

2.1.7 优化方案

1️⃣使用 PRPL 模式实现即时加载
  1. 推送 (Push)(或预加载)最重要的资源。
  1. 尽快渲染 (Render) 初始路线。
  1. 预缓存 (Pre-cache) 剩余资产。
  1. 延迟加载 (Lazy load) 其他路线和非关键资产。
3️⃣优化阻塞渲染的 JS 和 CSS
4️⃣改进服务器处理内容的方式和位置
  1. 使用CDN加速
  1. 优先使用缓存提供 HTML 页面
  1. 尽早建立第三方连接
5️⃣优化最大内容绘制考量的元素
  1. 优化和压缩图像
  1. 预加载重要资源
  1. 压缩文本文件
  1. 基于网络连接交付不同资产(自适应服务)
  1. 使用 Service Worker 缓存资产
6️⃣优化渲染方式
  1. 使用服务端渲染(会影响TTFB和TTI)
  1. 使用预渲染
  1. 最小化关键 JS(压缩JS代码,延迟加载未使用的JS)
 

2.2 CLS

2.2.1 什么是CLS

CLS累积布局偏移是指一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧,就发生了局偏移页面内容的意外移动通常是由于异步加载资源,或者动态添加 DOM 元素到页面现有内容的上方造成的。 💡只有当现有元素的起始位置发生变更时才算作布局偏移。如果将新元素添加到 DOM 或是现有元素更改大小,则不算作布局偏移,前提是元素的变更不会导致其他可见元素的起始位置发生改变。

2.2.2 如何优化

  1. 使用动画和过渡
  1. 始终在图像和视频元素上包含尺寸属性,或者通过使用CSS 长宽比容器之类的方式预留所需的空间
  1. 除非是对用户交互做出响应,否则切勿在现有内容的上方插入内容

2.3 FID

2.3.1 什么是FID

FID 首次输入延迟将用户尝试与无响应页面进行交互时的体验进行了量化,测量从用户第一次与页面交互直到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。低 FID 有助于让用户确信页面是有效的
是否正在发生?
导航是否成功启动?服务器有响应吗?
是否有用?
是否渲染了足够的内容让用户可以深入其中?
是否可用?
页面是否繁忙,用户是否可以与页面进行交互?
是否令人愉快?
交互是否流畅自然,没有延迟和卡顿?
⚠️和INP一样会存在不展示FID的情况

2.3.2 哪些算是首次输入

FID 只关注不连续操作对应的输入事件,如点击轻触按键。其他诸如滚动缩放之类的交互属于连续操作,具有完全不同的性能约束(而且,浏览器通常能够通过在单独的线程上执行这些操作来隐藏延迟)。

2.3.3 如何优化

  1. 分割长任务
  1. JS代码优化,压缩代码体积
    1. 代码分割(按需加载)
    2. 对关键路径或首屏内容不需要的脚本使用 async 或 defer
    3. 最大限度减少未使用的 polyfill
  1. 将更多逻辑转移到服务器端,或在构建期间静态生成更多内容
  1. 减少数据获取依赖:
    1. 尽量最大限度地减少对级联数据获取的依赖
    2. 尽量最大限度地减少需要在客户端进行后处理的数据量
  1. 优化第三方脚本执行
    1. 按需加载第三方代码
    2. 延迟加载
  1. 使用 Web Worker
 

2.4 FCP

只会捕获加载体验最开始的部分

2.4.1 什么是FCP

FCP 首次内容绘制是衡量用户感知的重要的加载性能指标,关注的是第一个内容元素(文本、图像、背景图像、<svg>元素或非白色的<canvas>元素)的渲染时间 反映了页面加载速度对用户可见内容的影响。
FCP 发生在第二帧,因为那是首批文本和图像元素在屏幕上完成渲染的时间点
FCP 发生在第二帧,因为那是首批文本和图像元素在屏幕上完成渲染的时间点

2.4.2 如何优化

大部分和LCP的优化方式相同
  1. 消除阻塞渲染的资源
  1. css优化
    1. 缩小 CSS
    2. 移除未使用的 CSS
  1. 预连接到所需的来源
  1. 减少服务器响应时间 (TTFB)
  1. 避免多个页面重定向
  1. 预加载关键请求
  1. 避免巨大的网络负载
  1. 使用高效的缓存策略服务静态资产
  1. 避免 DOM 过大
  1. 最小化关键请求深度
  1. 确保文本在网页字体加载期间保持可见
  1. 保持较低的请求数和较小的传输大小
 

2.5 INP

2.5.1 什么是INP

INP 下次绘制交互观察用户与页面进行的所有交互延迟,并报告所有(或几乎所有)交互都低于的单个值。低 INP 意味着页面始终能够快速响应所有(或绝大多数)用户交互。INP 的目标是确保对于用户进行的所有或大多数交互,从用户发起交互到绘制下一帧的时间尽可能短。

2.5.2 不报告INP的情况

  1. 页面已加载,但用户从未单击、点击或按下键盘上的按键
  1. 页面已加载,但用户使用不涉及单击、点击或使用键盘的手势与页面进行交互,例如滚动或悬停
  1. 该页面正在由机器人(例如搜索爬虫或无头浏览器)访问,但尚未编写脚本来与该页面交互

2.5.3 优化方案(JS)

1️⃣优化输入延迟:
  1. 避免重复计时器启动过多的主线程工作
  1. 避免长时间的任务
  1. 注意用户交互的重叠,可对输入进行去抖动,注意JavaScript 中的动画可能会引发许多requestAnimationFrame调用,这可能会妨碍用户交互,尽可能使用 CSS 动画,避免非合成动画
2️⃣优化事件回调:
  1. 分解长任务,不要阻塞主线程
    1. 当任务被分解时,浏览器有更多机会响应更高优先级的工作,其中包括用户交互
      当任务被分解时,浏览器有更多机会响应更高优先级的工作,其中包括用户交互
  1. 分解JS代码为更小的功能,合理使用setTimeout()等可以将代码执行推迟到后续任务的API
  1. 使用 async/await 来创建让出点
  1. 在必要的时候使用isInputPending()来让出主线程
3️⃣最大限度地减少演示延迟
  1. 保持初始 DOM 较小
  1. 尽量少的使用 JavaScript 渲染 HTML
 

2.6 TTFB

2.6.1 什么是TTFB

TTFB 第一字节时间是一个衡量对资源的请求和响应的第一个字节开始和到达之间时间的指标。TTFB的衡量要快于FCP和LCP,也就是从打开页面开始,到加载出页面的那一段等待时间。
网络请求阶段及其相关时间损耗的图示. TTFB 测量startTime和responseStart之间的时间损耗
网络请求阶段及其相关时间损耗的图示. TTFB 测量startTimeresponseStart之间的时间损耗
TTFB 是下列请求节点的时间损耗汇总:
  • Redirect time 重定向时延
  • Service worker 启动时延(如果适用)
  • DNS 查询时延
  • 建立连接和 TLS 所消耗时延
  • 请求,直到响应的第一个字节到达为止的时延
减少连接建立后端服务的时延将有助于降低 TTFB。
⚠️注意:TTFB 并不是核心Web指标,如果并不太影响Web核心指标,优化需求并不是很高

2.6.2 如何优化 TTFB

TTFB 的值会过高,在很大程度上取决于托管供应商后端服务通常通过选择一个合适的托管供应商是优化 TTFB 的高效方案 ,其基础设施可确保高正常运行时间和响应能力,与高级 CDN 服务相结合,效果会更好。同时后端服务的数据库垃圾过多,或者查询次数过多,也会影响TTFB的数值。
  • 避免多次重定向.
  • 使用 <link rel="preconnect"> 标签,提前向跨域资源源建立预连接。
  • 使用HSTS预加载列表,以消除 HTTP 转 HTTPS 的重定向延迟。
  • 使用 HTTP/2 or HTTP/3,以提供更高的网络性能和效率。
  • 考虑预测性预取:使用 <link rel="prefetch"> 或 <link rel="dns-prefetch"> 标签,为没有指定减少数据使用偏好的用户提供快速页面导航。
  • 在可能和适当的情况下,使用服务器端生成(SSG)来代替服务端渲染(SSR)的标记。
 

2.7 SI

2.7.1 什么是SI

SI 速度指数,是衡量页面加载期间内容视觉显示的速度指标,以秒为单位。SI指标的计算是通过模拟用户在页面加载过程中不断更新视图的情况来实现的。它考虑了整个页面的可见区域以及内容加载的顺序和时间,以及渲染完成的时间。SI分数越低,说明页面越快呈现出有意义的内容。

2.7.2 如何优化

  1. 分解长任务
  1. 优化JS代码(压缩、分割、删除,使用PRPL模式)
  1. 确保文本在网络字体加载期间保持可见
 

2.8 TBT

2.8.1 什么是TBT

TBT总阻塞时间测量页面被阻止响应用户输入(例如鼠标单击、屏幕点击或键盘按下)的总时间。总和是通过添加 FCP 首次内容渲染Time to Interactive 页面资源加载成功并能响应用户交互的时间点(已退役指标)之间所有长任务的阻塞部分来计算的。任何执行时间超过 50 毫秒的任务都是长任务。50 毫秒之后的时间量是阻塞部分。例如,如果 Lighthouse 检测到一个 70 毫秒长的任务,则阻塞部分将为 20 毫秒。

2.8.2 如何优化

  1. 分解长任务
  1. JS代码优化(压缩、分割、重构、删除,合理加载第三方JS代码)
 

3 案例

1️⃣使用浏览器的控制台打开lighthouse,查看本地3000端口网站的性能情况
lighthouse 报告总共五个重要性能指标,此网站TBT性能中等
lighthouse 报告总共五个重要性能指标,此网站TBT性能中等
 
2️⃣查看TBT详细解析
指出以下两个长任务导致TBT时间延长
指出以下两个长任务导致TBT时间延长
⁉️指出问题:
js文件太大
💡建议优化:
对JS代码进行压缩、分割、重构、删除,合理加载第三方JS代码等方式来优化
 
3️⃣FCP 指标为快速,但是有可优化的地方
报告指出发现一个链式请求,是一个css文件,这个文件是以高优先级加载的,回导致加载时间过长
报告指出发现一个链式请求,是一个css文件,这个文件是以高优先级加载的,回导致加载时间过长
⁉️指出问题:
css文件太大
💡建议优化:
对css代码进行分解或删除部分重复代码
 
4️⃣LCP指标为快速,但是有可以优化的地方
此处指出该img是视口内的最大绘制元素,但是却被延迟加载了,会导致LCP的延迟
此处指出该img是视口内的最大绘制元素,但是却被延迟加载了,会导致LCP的延迟
⁉️指出问题:
视口最大绘制元素延迟加载了
💡建议优化:
优化关键渲染路径,LCP元素不用延迟加载
此处指出页面使用了大量的网络负载,总大小为 3,510 KiB,它提醒大型网络负载会导致用户产生实际的费用,并且与长加载时间高度相关
此处指出页面使用了大量的网络负载,总大小为 3,510 KiB,它提醒大型网络负载会导致用户产生实际的费用,并且与长加载时间高度相关
⁉️指出问题:
图片和文件太大
💡建议优化:
进行资源压缩、代码分割、资源缓存、延迟加载、使用现代图像格式等方式来优化
 
 
 
推荐文章:
相关文章
ts在实际项目中的应用JS 基础记录