回流和重绘
资料你真的了解回流和重绘吗 - SegmentFault 思否回流与重绘 - 掘金 (juejin.cn)面试官:怎么理解回流跟重绘?什么场景下会触发? | web前端面试 - 面试官系列 (vue3js.cn)浏览器渲染过程渲染页面:浏览器的工作原理 - Web 性能 | MDN (mozilla.org)解析HTML,形成DOM树,当遇到非阻塞资源时,如图片则会继续解析,当遇到css文件时,也
·
资料
浏览器渲染过程
渲染页面:浏览器的工作原理 - Web 性能 | MDN (mozilla.org)
- 解析HTML,形成DOM树,当遇到非阻塞资源时,如图片则会继续解析,当遇到css文件时,也会继续解析。当时遇到了
js
文件(特别是没有defer和async)的阻塞渲染并停止HTML的解析。 - 构建CSSOM树。浏览器将CSS规则转换为可以理解和使用的样式映射。浏览器遍历CSS中的每个规则集,根据CSS选择器创建具有父、子和兄弟关系的节点树。
- 第三步是将DOM和CSSOM组合成一个Render树,计算样式树或渲染树从DOM树的根开始构建,遍历每个可见节点。像和它的子节点以及任何具有
display: none
样式的结点,例如script { display: none; }
(在user agent stylesheets可以看到这个样式)这些标签将不会显示,也就是它们不会出现在Render树上。具有visibility: hidden
的节点会出现在Render树上,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理默认值,因此上面代码示例中的script节点将不会包含在Render树中。 - 第四步是在渲染树上运行布局以计算每个节点的几何体。(回流\重排)。在此阶段,考虑到视区大小,浏览器将确定屏幕上所有不同框的尺寸。以视区的大小为基础,布局通常从body开始,用每个元素的框模型属性排列所有body的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。
- 最后一步是将各个节点绘制到屏幕上。
回流一定会触发重绘,重绘不一定会触发回流。
生成渲染树
- 从DOM树的根开始构建,遍历每个可见节点。
- 对于每一个可见节点,找对应的CSSOM规则。
- 根据每一个可见节点和它们对应的CSSOM规则,结合形成Render Tree.
不可见节点:
- Head标签下的所以子节点(meta、link)。
- script。
- display : none 的元素
- 利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。
回流
以视区的大小为基础,布局通常从body开始,用每个元素的框模型属性排列所有body的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。
总的来说就是计算它们在设备视口(viewport)内的确切位置和大小(也就是几何属性和位置),这个计算的阶段就是回流。
重绘
我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点。也就是在屏幕上绘制图形,但是如背景颜色发生改变,那么会引起重绘,但是不会引发回流。
触发回流重绘的操作
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
浏览器的优化机制
减少回流和重绘的方法
-
把多个操作DOM操作合并在一起—使用csstext或者class
-
使得节点脱离文档流(也就是不可见的节点),操作,回到文档流。
- 使用display: none
-
必须触发布局事件
也就是offset这些。若多次使用到同一个offset,那么可以先把它的值保存起来再使用。
-
对于复杂的动画可以使用绝对定位使其脱离文档流。对于复杂动画效果,由于会经常的引起回流重绘,因此,我们可以使用绝对定位,让它脱离文档流。否则会引起父元素以及后续元素频繁的回流。
更多推荐
已为社区贡献1条内容
所有评论(0)