回流和重绘
结论
回流一定重绘,重绘不一定回流
浏览器怎么处理工作?
浏览器通过渲染引擎和JS引擎来处理工作,并且不同浏览器的引擎也不同
浏览器的渲染过程
1、访问页面,浏览器解析HTML代码,生成DOM树,HTML标签在DOM树上都有对应的节点
2、在构建DOM树的同时也会解析CSS样式表,生成CSS对象模型树(CSSOM)
(很浪费资源,因为样式有些会继承,因此选择器尽量选择id和class)
3、浏览器将DOM树和CSSOM合并成为渲染树(Render tree)【只包含可见节点】
4、浏览器会根据渲染树进行布局,现阶段会确定节点是否可见并精确他们的位置和尺寸,回流
5、根据渲染树和回流得到位置、大小,得到节点的绝对像素,重绘
6、Display将像素发送给GPU,展示在页面上
回流
回流:渲染生成后,需要计算他们在视口确切的大小和位置,这个计算阶段称为回流
重绘
重绘:通过构建渲染树和回流,我们知道的哪些节点可见,并知道样式的位置和大小,我们就将渲染树的每个节点转换为屏幕的真实像素,这一阶段称为重绘
何时触发回流重绘?
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的
怎么减少回流重绘?
1)修改样式的时候通过 css 类名修改或通过 cssText 修改。
2)DOM 元素离线修改—>隐藏元素,应用修改,重新显示。(浏览器本身也会有优化)
3)避免触发同步布局事件,如获取 offsetWidth 等属性值,因为会强制浏览器刷新队列。
4)使用绝对定位让复杂动画脱离文档流减少父元素以及后续元素频繁的回流。
5)使用css3硬件加速,可以让 transform、opacity、filters、will-change 这些动画不会引起回流重绘 (会提高内存占用)