页面生存周期
- 加载阶段:是指从发出请求到渲染出完整页面的过程,影响到这个阶段的主要因素有网络和 JavaScript 脚本。
- 交互阶段:主要是从页面加载完成到用户交互的整合过程,影响到这个阶段的主要因素是 JavaScript 脚本。
- 关闭阶段:主要是用户发出关闭指令后页面所做的一些清理操作。
加载阶段影响渲染的因素

能阻塞网页首次渲染的资源称为关键资源
- 关键资源个数
- 关键资源大小
- 请求关键资源需要多少个RTT(Round Trip Time)
RTT 就是这里的往返时延。它是网络中一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认,总共经历的时延。通常 1 个 HTTP 的数据包在 14KB 左右
- 如何减少关键资源的个数
- 将 JavaScript 和 CSS 改成内联的形式
- 如果 JavaScript 代码没有 DOM 或者 CSSOM 的操作,则可以改成 async 或者 defer 属性
- 对于 CSS,如果不是在构建页面之前加载的,则可以添加媒体取消阻止显现的标志
- 如何减少关键资源的大小
- 压缩 CSS 和 JavaScript 资源,移除 HTML、CSS、JavaScript 文件中一些注释内容
- 如何减少关键资源RTT的次数
- 减少关键资源的个数和减少关键资源的大小搭配来实现
- 使用 CDN 来减少每次 RTT 时长
交互阶段影响渲染的因素
谈交互阶段的优化,其实就是在谈渲染进程渲染帧的速度,因为在交互阶段,帧的渲染速度决定了交互的流畅度

- 如果在计算样式阶段发现有布局信息的修改,那么就会触发 重排 操作,然后触发后续渲染流水线的一系列操作
- 如果在计算样式阶段没有发现有布局信息的修改,只是修改了颜色一类的信息,那么就不会涉及到布局相关的调整,所以可以跳过布局阶段,直接进入绘制阶段,这个过程叫 重绘
- 通过 CSS 实现一些变形、渐变、动画等特效,这是由 CSS 触发的,并且是在合成线程上执行的,这个过程称为合成。因为它不会触发重排或者重绘,而且合成操作本身的速度就非常快,所以执行合成是效率最高的方式
优化方案
- 减少 JavaScript 脚本执行时间(不要一次霸占太久主线程)
- 将一次执行的函数分解为多个任务,使得每次的执行时间不要过久
- 采用 Web Workers
- 避免强制同步布局
- 通过 DOM 接口执行添加元素或者删除元素等操作后,是需要重新计算样式和布局的,不过正常情况下这些操作都是在另外的任务中异步完成的,这样做是为了避免当前的任务占用太长的主线程时间
- 强制同步布局,是指 JavaScript 强制将计算样式和布局操作提前到当前的任务中
- 避免布局抖动
- 布局抖动,是指在一次 JavaScript 执行过程中,多次执行强制布局和抖动操作
- 合理利用 CSS 合成动画
- 合成动画是直接在合成线程上执行的,这和在主线程上执行的布局、绘制等操作不同,如果主线程被 JavaScript 或者一些布局任务占用,CSS 动画依然能继续执行
- 如果能提前知道对某个元素执行动画操作,那就最好将其标记为 will-change
- 避免频繁的垃圾回收