持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
核心描述
- 重排
- 是什么:重排也叫回流,当 DOM 的变化影响了元素的几何信息(元素的位置、尺寸大小等),浏览器需要重新计算元素的集合属性,将其安放在界面中的正确位置,这个过程叫做重排。
- 怎么引起重排
- 页面初始渲染
- 添加、删除可见的 DOM 元素
- 改变元素位置
- 改变元素尺寸,比如边距、填充、边框、宽度和高度等
- 改变元素的内容,比如文字数量,图片大小等
- 改变字体大小
- 改变浏览器窗口尺寸,比如 resize 事件发生时
- 激活 CSS 伪类,比如 :hover
- 设置 style 属性的值,因为通过设置 style 属性改变结点样式的话,每一次设置都会触发一次 reflow
- 查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等,除此之外,当我们调用 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发重排,原理是一样的
- 重绘
- 是什么:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。
- 怎么引起重绘
- 修改 color、background 、border-style、boder-radius 等等只影响外观但不影响布局的属性
- 区别
- 重排一定引起重绘,重绘不一定引起重排
- 重绘比重排省去了布局和分层阶段,直接进入了绘制
知识拓展
- 重排的影响范围:
- 全局范围:从根节点 html 开始对整个渲染树进行重新布局
- 局部范围:对渲染树的某部分或者某一个渲染对象重新布局
- 如:把一个 dom 的宽高之类的集合信息固定,然后再 dom 内部触发重排,就只会重新渲染该 dom 内部的元素,而不会影响到外界
- 减少重排、重绘的优化方法
- 减少重排范围,尽量将需要重排的内容固定在局部范围
- 减少重排次数
- 样式集中改变,如能通过类名进行改版样式,尽量不要通过 js 一个属性一个属性的改变样式
- 分离读写操作,当需要 js 操作元素样式时,即将获取样式属性的操作集中执行,并缓存值,在需要设置样式属性时也集中处理,避免获取和设置的操作互相夹杂。因为获取、设置的操作都会引起重排
- 将 DOM 离线,即当某个元素短期内不需要渲染时,可以考虑将其设置为 display:none,在积攒比较多的变更后,设置为可见,而仅造成一次重排重绘
- 使用 absolute 或 fixed 脱离文档流,这可以仅对局部范围的元素进行重排
- 合理使用 css 动画,可以利用 GPU 直接合成元素样式,而避免重排、重绘
- DOM 渲染流程:DOM 树解析->样式计算->布局->分层->绘制->分块->光栅化->合成
- CSSOM、渲染树在新版本的 Chrome 架构中已经不存在,渲染流程变成了上述的过程
参考资料
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。