浏览器的渲染过程
- 处理 HTML 标记并构建 DOM 树。
- 处理 CSS 标记并构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树。
- 根据渲染树来布局(Layout),以计算每个节点的几何信息。
- 将各个节点绘制到屏幕上。
回流
当浏览器发现某一部分发生了变化而影响了布局,这个时候就要倒回去重新渲染,这个回退的过程叫回流。
重绘
当我们改变了一个元素的颜色、背景色、边框颜色等不影响它周围和内部布局的属性时,屏幕的一部分需要重画,但是元素的几何尺寸和位置没有发生变化。
关键渲染路径优化
- 使用CDN
- 使用压缩
- 合理使用缓存
- 减少http请求的次数
避免回流的优化
- 避免操作DOM,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
- 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中。如读取offsetLeft等属性。
- 尽可能在DOM树的末端改变class ,尽可能在DOM树的里面改变class,可以限制回流的范围,使其影响尽可能少的节点。
- 避免设置多层内联样式,因为每一个都会造成回流,样式合并在一个外部类,这样当该元素的class属性被操作时,只会产生一个reflow。
- 将需要多次回流的元素position属性设为absolute或fixed,这样该元素就会脱离文档流,它的变化不会影响其他元素变化。比如动画效果应用到position属性为absolute或fixed的元素上。
- 牺牲平滑度换取速度,动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动
- 避免使用table布局,在布局完全建立之前,table需要很多关口,table是可以影响之前已经进入的DOM元素的显示的元素。即使一些小的变化和会导致table中所有其他节点回流。
- 避免使用css的JavaScript表达式,该规则较过时,但是个好主意。因为每次都需要重新计算文档,或部分文档、回流。