先看看浏览器是如何渲染网页的 
从图中可以看到,网页的渲染是分为两个部分的,HTML和CSS
- 解析HTML生成dom树、解析CSS生成样式规则
 - 合成dom树和样式,形成渲染树
 - 渲染树回流(Layout),再生成渲染树,渲染好之后重绘
 - 最后展示在浏览器上
 
从图中还能得出一个结论: 回流必引起重绘
回流
通过构造render树,把dom节点和对应的css样式结合起来,但是浏览器还需要计算设备窗口大小,dom该如何展示,这个阶段叫做回流
重绘
最终,我们通过构造渲染树和回流阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(位置、大小),那么我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点。
何时发生回流重绘
回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况
- 添加或删除dom元素
 - 元素位置发生改变
 - 元素尺寸发生变化
 - 页面刚渲染时
 - 浏览器窗口大小变化
 
浏览器的优化机制
现代浏览器的优化思想跟react、vue类似,批量渲染,把一系列的更新放在队列里面,当达到一定的阈值后,更新并清空队列。 这时候有个问题了,我们使用JS获取dom节点信息岂不是不准了? 所以浏览器有个强制回流机制,也就是当我们获取dom节点信息时,浏览器为了返回最新的dom节点信息给我们,不得不强行回流 比如使用这些方法:
- offsetTop
 - scrollTop
 - clientTop
 - getComputedStyle()
 - getBoudingClienRect()
 - …
 
所以,使用这些方法时,尽量把值缓存下来,这样也是优化性能的做法
如何更优的渲染网页呢?
如果我们频繁修改dom,可以这样优化:
- 使dom脱离文档流
 - 修改dom
 - 把dom加入文档流
 
1、3步骤会造成回流,但是由于脱离了文档流, 修改dom不会造成回流了 脱离文档流的方法:
- 隐藏dom (display:none)
 - 绝对定位
 - 把dom拷贝到到一个脱离网页的节点中
 
复杂动画,使用绝对定位
css3硬件加速
比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘。这个时候,css3硬件加速就闪亮登场了 常见的触发硬件加速的css属性:
- transform
 - opacity
 - filters
 - Will-change