一 目录
不折腾的前端,和咸鱼有什么区别
| 目录 |
|---|
| 一 目录 |
| 二 前言 |
| 三 浏览器渲染过程 |
| 四 重绘 |
| 五 回流 |
| 六 优化 |
| 七 参考文献 |
二 前言
- 什么是回流?
- 什么情况下触发回流?
- 什么是重绘?
- 什么情况下触发重绘?
- 如何避免回流和重绘?
三 浏览器渲染过程
如上图,浏览器的渲染过程为:
- 解析 HTML,生成
DOM树 - 解析 CSS,生成
CSS 规则树(CSS Rule Tree) - 将
DOM Tree和CSS Rule Tree相结合,生成 渲染树(Render Tree) - 从根节点开始,计算每一个元素的大小、位置,给出每个节点所应该出现的屏幕精确坐标,从而得到基于渲染树的 布局渲染树(
Layout of the render tree)。 - 遍历渲染树,将每个节点用
UI渲染引擎来绘制,从而将整棵树绘制到页面上,这个步骤叫 绘制渲染树(Painting the render tree)
这个过程面试中非常常见,小伙伴们稍微记一下,后面章节会反复提及。
四 重绘
- 什么是重绘?
重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少。
在浏览器渲染过程中,对应步骤 5,即每次发生重绘,我们都会重新绘制渲染树,然后进行展示。
- 如何触发重绘?
- 修改背景色、颜色(
background、color) - 设置可见度(
visibility) - 设置背景图(
background-image) - ……等
五 回流
- 什么是回流?
回流(reflow):又叫重排(layout)。当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。
此时,浏览器需要重新经过计算,计算后还需要重新页面布局,然后进行绘制渲染,因此是较重的操作。
- 如何触发回流?
- 添加删除 DOM 元素
- 改变边框、边距、宽高(
border、margin、padding、width、height) - 浏览器改变窗口(
resize) - ……等
六 优化
这时候需要一句总结:
- 回流必定会发生重绘,重绘不一定会引发回流。
看图理解:回流动了 Layout,触发了 Render Tree 进行重新渲染,所以后面还会 Painting。而重绘后面直接 Display,不会触发回流。
当然,很多浏览器都会优化操作:
浏览器会维护 1 个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会处理队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。
那么,我们做一道题:
输出下面回流和重绘的次数:
var s = document.body.style;
s.padding = "2px";
s.border = "1px solid red";
s.color = "blue";
s.backgroundColor = "#ccc";
s.fontSize = "14px";
document.body.appendChild(document.createTextNode('abc!'));
答案:触发回流 4 次,触发重绘 6 次。
在这里,我们需要了解的是:
- JS 是单线程的,JS 解析的时候渲染引擎是停止工作的。
所以,结合这些内容,我们可以根据此大概说一下:
- 如何减少回流和重绘?
- 【CSS】使用
visibility替换display - 【CSS】避免
table布局。对于Render Tree的计算通常只需要遍历一次就可以完成,但是table布局需要计算多次,通常要花 3 倍于等同元素的时间,因此要避免。 - 【JS】避免频繁做
width、height等会触发回流的操作。 - 【JS】操作 DOM 的时候,如果是添加 DOM 节点,可以将所有节点都在 JS 中操作完毕,再进行渲染(一次性)
七 参考文献
- 浏览器的回流与重绘 (Reflow & Repaint)【阅读建议:10min】
- 你真的了解回流和重绘吗【阅读建议:10min】
- 页面重绘和回流以及优化【阅读建议:5min】
- 浏览器重绘(repaint)重排(reflow)与优化[浏览器机制]【阅读建议:10min】
- 回流与重绘:CSS性能让JavaScript变慢?【阅读建议:10min】
jsliang 的文档库由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。
基于 github.com/LiangJunron… 上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。