当前位置:网站首页>重排 (reflow) 与重绘 (repaint)
重排 (reflow) 与重绘 (repaint)
2022-06-10 21:23:00 【与BUG战斗的小绵羊】
前言
本文依旧是日常学习总结篇,主要是要理解浏览器的重排与重绘。
一、浏览器解析渲染页面过程

当浏览器获得一个 html 文件时,会 "自上而下" 加载,并在加载过程中进行解析渲染。
- 获取 HTML 文件并进行解析,生成 DOM 树;
- 解析 HTML 的同时也会解析 CSS,生成 CSSOM 树;
- 将 DOM 树和 CSSOM 树结合,生成渲染树 (Render Tree);
- 根据生成的渲染树,进行布局 (Layout) (重排),得到节点的几何信息(位置,大小);
- 根据渲染树以及重排得到的几何信息,进行绘制 (Painting) (重绘),调用 GPU (图形处理器) 将元素呈现出来。
二、重排 (reflow)
重排也叫回流,当 DOM 的变化影响了元素的几何信息(位置、尺寸大小等),浏览器需要重新计算元素的几何属性,将其安放在界面的正确位置,这个过程叫做重排。
重排触发时机:
- 页面初始渲染,这是开销最大的一次重排,并且避免不了;
- 添加或删除可见的 DOM 元素;
- 元素的位置发生变化;
- 元素的尺寸发生变化(包括外边距、内边距、边框大小、高度和宽度等);
- 元素内容发生变化(例如文字数量、图片大小等);
- 元素字体大小改变;
- 改变浏览器窗口尺寸(例如 resize 事件发生时);
- 激活 CSS 伪类(例如 :hover);
- 设置 style 属性的值,因为通过设置 style 属性改变节点样式的话,每一次设置都会触发一次重排;
- 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight 等,除此之外,当我们调用 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发重排,原理是一样的,都为求一个 “即时性” 和 “准确性” 。
| width | height | margin | padding |
| display | border-width | border | position |
| overflow | font-size | vertical-align | min-height |
| clientWidth | clientHeight | clientTop | clientLeft |
| offsetWidth | offsetHeight | offsetTop | offsetLeft |
| scrollWidth | scrollHeight | scrollTop | scrollLeft |
| scrollIntoView() | scrollTo() | getComputedStyle() | scrollIntoViewIfNeeded() |
| getBoundingClientRect() |
重排影响的范围:
由于浏览器渲染界面是基于流失布局模型的,所以触发重排时会对周围 DOM 重新排列,影响的范围有两种:
- 全局范围:从根节点 html 开始对整个渲染树进行重新布局;
- 局部范围:对渲染树的某部分或某一个渲染对象进行重新布局。
三、重绘 (repaint)
当一个元素的外观发生变化,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
重绘触发时机:
- 颜色的改变;
- 文本方向的改变;
- 阴影的改变等。
| color | border-style | visibility | background |
| text-decoration | background-image | background-position | background-repeat |
| outline-color | outline | outline-style | border-radius |
| outline-width | box-shadow | background-size |
四、重排与重绘的关系
重排一定导致重绘,重绘不一定导致重排。
每个页面初始化渲染时至少触发一次重排和重绘。
重排和重绘的代价都很高昂,频繁重排重绘,会破坏用户体验,让页面显示变迟缓。
所以我们要尽可能避免频繁触发重排和重绘,尤其是重排。
五、如何尽量避免重排重绘
️、浏览器对于重排和重绘的优化
浏览器会维护一个队列,把所有会引起重排、重绘的操作放入这个队列,等队列中的操作到了一定数量或者到了一定的时间间隔,浏览器就会 flush 队列,进行一个批处理。这样就会让多次的重排、重绘变成一次重排重绘。
但当你获取布局信息的操作的时候,例如 offsetTop 等方法,为了保证获取结果的准确性,就会打破浏览器的这种优化策略,强制浏览器提前 flush 队列。
️、css 中避免重排和重绘
- 减少重排范围,尽量将需要重排的内容固定在局部范围。
- 不要使用 table 布局,可能很小的一个改动会造成整个 table 的重新布局。不得已使用 table 的场景,可以设置 table-layout: auto; 或者 table-layout: fixed; 这样可以让 table 一行一行的渲染,同时可可以限制重排的影响范围。
- 集中修改样式。这样可以尽可能利用浏览器的优化机制,一次重排重绘就完成渲染。
- 避免设置多项内联样式。
- 如果想设定元素的样式,可以通过改变元素的 class 类名(尽可能在 DOM 树的最里层)。
- 将 DOM 离线。通过设置元素属性 display: none; 将其从页面上去掉,然后再进行后续操作,这些后续操作将不会出发重排重绘,最后通过 display 属性显示。另外,visibility: hidden 的元素只对重绘有影响,不影响重排。
- 使用 position: absolute / fixed; 脱离文档流。例如那些复杂的动画,对其设置 position: absolute / fixed; 尽可能地使元素脱离文档流,从而减少对其他元素的影响。
- 利用 transform translate 去代替 left top 的变换。
- 使用 css3 硬件加速,可以让 transform、opacity、filters 这些动画不会引起重排重绘。
- 避免使用 css 的 JavaScript 表达式。
- 将频繁重排或重绘的节点设置为图层。将节点设置为 video 或 iframe;为节点添加 will-change 属性。
️、js 中避免重排和重绘
- 减少直接操作 DOM 元素。不要一条一条地修改 DOM 的样式,改用 className 来控制。
- 分离读写操作。当需要 js 操作元素样式时,即将获取样式属性的操作集中执行,并缓存值,在需要设置样式属性时也集中处理,避免获取和设置的操作互相夹杂。因为获取、设置的操作都会引起重排。
- 动态插入多个节点时,可以使用文档碎片(DocumnetFragment),创建后一次插入,避免多次的渲染性能。DocumnetFragment 是一个保存多个元素的容器对象(保存在内存),当更新其中的一个或者多个元素时,页面不会更新。
- 不要把 DOM 节点的 offsetLeft 等属性值放在一个循环里当成循环里的变量。
- 使用 resize 事件时,做防抖和节流处理。
边栏推荐
- [tcapulusdb knowledge base] tcapulusdb machine initialization and launch introduction
- SQL server queries are case sensitive
- 数组 移动0
- Visio to high quality pdf
- String inversion
- Latex error: file ‘xxx. sty‘ not found
- 创新探索层层加码,容智流程挖掘领域模式趋向成熟
- GMPNN:Drug-drug interaction prediction with learnable size-adaptive molecular substructures.
- [tcapulusdb knowledge base] Introduction to tcapulusdb process startup
- [tcapulusdb knowledge base] tcapulusdb viewing process status introduction
猜你喜欢

Icml2022 | sharp maml: model independent meta learning for sharpness perception
![[tcapulusdb knowledge base] Introduction to tcapulusdb process startup](/img/df/08a5e9b939ab158a86c75c92697864.png)
[tcapulusdb knowledge base] Introduction to tcapulusdb process startup

中小型会议如何进行数字化升级?

What about the popular state management library mobx?

SQL exercise 4: string processing function

Array union set

C#使用S7.net连接西门子S1200PLC,C#直接连接西门子PLC

Tcapulusdb Jun · industry news collection (VI)

Tcapulusdb Jun · industry news collection (III)

How to do well in the top-level design of informatization in the process of informatization upgrading of traditional enterprises
随机推荐
C use s7 Net connected to Siemens s1200plc, C # directly connected to Siemens PLC
String search in C
[MySQL] summary of common data types
leetcode:333. 最大 BST 子树
Ceph分布式存储集群Pool资源池的概念以及使用
【TcaplusDB知识库】TcaplusDB机器初始化和上架介绍
Sealem finance builds Web3 decentralized financial platform infrastructure
[C] overide can override the virtual method inherited from a higher parent
What about the popular state management library mobx?
GMPNN:Drug-drug interaction prediction with learnable size-adaptive molecular substructures.
How to do well in the top-level design of informatization in the process of informatization upgrading of traditional enterprises
Matlab - 演化博弈论实现
记录(三)
[tcapulusdb knowledge base] tcapulusdb refresh tbus channel introduction
Concept and use of CEPH distributed storage cluster pool resource pool
TcaplusDB君 · 行业新闻汇编(四)
Solution de gestion de la zone pittoresque intelligente pour la réunion des baleines
Apache相关的几个安全漏洞修复
C程序实例1--个人通讯录管理系统
Bitwise and shift operators