从4个角度,评估用户体验
当用户访问一个页面的时候,通常会从视觉上去感知是不是页面已经如预期地加载完成可以正常使用了。
主题 | 说明 |
---|---|
发生了吗? | 页面是否开始跳转?服务器有没有响应? |
内容重要吗? | 重要的内容是否已经渲染? |
可以使用吗? | 页面可交互了吗?或者还在加载中吗? |
体验好吗? | 交互是否平滑自然,没有卡顿? |
发生了吗?
- FCP ⾸次内容绘制时间 (First contentful paint)
内容重要吗?
- LCP 最⼤内容绘制时间 (Largest contentful paint)
可以使用吗?
-
FID ⾸次输⼊延迟 (First input delay)
-
TBT 主线程累计阻塞时间 (Total blocking time)
-
TTI 页⾯可交互时间 (Time to Interactive)
-
确保页面可交互的js没有下载完成
-
存在长任务(长于50毫秒的任务)
体验好吗?
- CLS 累计布局偏移 (Cumulative layout shift)
- 存在长任务(长于50毫秒的任务)
https://storage.googleapis.com/web-dev-assets/layout-instability-api/layout-instability2.mp4
将指标关联到用户体验
回到我们以前认为对用户体验最重要的问题,本表概述了我们刚刚列出的每个指标如何映射到我们希望优化的用户体验:
体验 | 指标 |
---|---|
发生了吗? | FCP |
内容重要吗? | LCP |
可以使用吗? | FID TBT TTI |
体验好吗? | CLS 长任务 |
性能优化和防性能退化
优化加载过程 (FCP/LCP/TTI/FID/TBT/CLS/TTI)
-
优化关键资源Html,js,css
- 关键资源个数
a. JavaScript 和 CSS,改成内联模式
b. 如果 JavaScript 代码没有 DOM 或者 CSSOM 的操作,则可以改成 async 或者 defer 属性
c. CSS,如果不是在构建页面之前加载的,则可以添加媒体取消阻止显现的标志
d. 当 JavaScript 标签加上了 async 或者 defer、CSSlink 属性之前加上了取消阻止显现的标志后,它们就变成了非关键资源了。 - 关键资源大小
a. 可以压缩 CSS 和 JavaScript 资源
b. 移除 HTML、CSS、JavaScript 文件中一些注释内容 - 关键资源请求需要多少个RTT
a. 减少关键资源的个数和减少关键资源的大小
b. 还可以使用 CDN 来减少每次 RTT 时长- 使用 TCP 协议传输一个文件时,比如这个文件大小是 0.1M,由于 TCP 的特性,这个数据并不是一次传输到服务端的,而是需要拆分成一个个数据包来回多次进行传输的。RTT 就是这里的往返时延。它是网络中一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认,总共经历的时延。通常 1 个 HTTP 的数据包在 14KB 左右,所以 1 个 0.1M 的页面就需要拆分成 8 个包来传输了,也就是说需要 8 个 RTT。
- 关键资源个数
优化交互过程
-
一个大的原则就是让单个帧的生成速度变快
-
减少 JavaScript 脚本执行时间
-
一种是将一次执行的函数分解为多个任务,使得每次的执行时间不要过久
-
采用 Web Workers
-
减少重排,重绘
- 如果在计算样式阶段发现有布局信息的修改,那么就会触发重排操作,然后触发后续渲染流水线的一系列操作
- 同样如果在计算样式阶段没有发现有布局信息的修改,只是修改了颜色一类的信息,那么就不会涉及到布局相关的调整,所以可以跳过布局阶段,直接进入绘制阶段,这个过程叫重绘
-
合理利用 CSS 合成动画
- 合成动画是直接在合成线程上执行的,这和在主线程上执行的布局、绘制等操作不同,如果主线程被 JavaScript 或者一些布局任务占用,CSS 动画依然能继续执行
- 如果能提前知道对某个元素执行动画操作,那就最好将其标记为 will-change,这是告诉渲染引擎需要将该元素单独生成一个图层
-
避免频繁的垃圾回收
- 在一些函数中频繁创建临时对象,那么垃圾回收器也会频繁地去执行垃圾回收策略
- 这样当垃圾回收操作发生时,就会占用主线程,从而影响到其他任务的执行,严重的话还会让用户产生掉帧、不流畅的感觉
- 所以要尽量避免产生那些临时垃圾数据。那该怎么做呢?可以尽可能优化储存结构,尽可能避免小颗粒对象的产生。
-
优化CLS
-
保证视觉稳定性
- 指定尺寸的图片
- 指定尺寸的广告、嵌入元素、iframe
- 避免在已存在的内容上方插入新内容
- 渲染自定义字体会引发布局偏移
- 优先考虑
transform
,而非会影响布局改变的属性 - 尽可能的在网络请求时,给一个loading,或者占位符提示,避免用户在这段时间内进行操作。