浏览器回流和重绘
重溯=重绘 回流=重排
● 浏览器使用费流式布局模型 ● 浏览器会把HTML解析为DOM,CSS解析为CSSOM,两个组合在一起称为 render树
重溯/重绘
当CSS或JS改变时 浏览器重新渲染 但 不会改变任意一个盒子的布局
称为浏览器重溯
如 改变元素的背景颜色、visibility等CSS
回流/重排
当CSS或JS改变时 浏览器重新渲染 但 会改变每一个盒子的布局
称为浏览器回流
如 改变某一盒子大小、添加或删除某一元素等
重溯和回流的时机
浏览器有一个特殊队列 据估计每隔16ms左右 将队列中所有触发重溯和回流的操作一起执行 优化体验
部分操作一旦触发会立刻引起重溯或回流 如下:
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- width、height
- getComputedStyle()
- getBoundingClientRect() 原因: 因为队列中可能会有影响到这些属性或方法返回值的操作,即使你希望获取的信息与队列中操作引发的改变无关,浏览器也会强行清空队列,确保你拿到的值是最精确的。
这里要注意的是
transform
虽然会发生位移,但他是在合成之后才发生的,不会影响回流和重绘的过程,他只是你结果的变换。不涉及布局的变化,渲染流水线是这样的顺序:重排 -> 重绘 -> 合成。transform: translate是直接合成,跳过了前面的重排重绘。
实际开发中:
回流消耗的性能高于重溯
提升性能的方法:多重溯少回流
比如:
- 用transform:translate()代替margin
- 少使用table table回流的性能消耗非常大 想一想就知道了
- 改变DOM时尽量在DOM树的最末端 影响范围小
- 带位移的动画效果给定位的元素
- 等等 自己想 不改变位置就行