浏览器的回流与重绘

277 阅读2分钟

前言

在我之前的文章里,我提到过:
渲染页面的过程包括构建DOM树和CSSOM树,同时具有DOM和CSSOM才能合并构建渲染树(Render Tree)。接着浏览器会根据渲染树来计算节点位置, 绘制节点。

当我们通过浏览器使用网页时,往往有可能会对元素节点的样式进行动态修改,比如改变颜色、宽高等。在执行这些动态修改时,浏览器可能会重新执行上面说的操作,我们统称为重绘和回流

回流

当render tree中的一部分或全部因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就称为回流(reflow)。当每个页面在第一次加载的时候,就需要一次回流。

注意:回流必将引起重绘,而重绘不一定会引起回流。

回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。

触发页面回流的因素

关键词: 影响布局 | 查询宽高、距离

一、CSS

1、盒子模型相关
width/height/padding/border/margin
2、节点文字相关
font/line-height/font-weight/
3、定位相关
postion/display/float/clear/

二、JS

1、增删 DOM 节点, 改变 DOM 节点的布局
2、计算元素的宽高、距离:
clientWidth、clientHeight、clientTop、clientLeft

offsetWidth、offsetHeight、offsetTop、offsetLeft

scrollWidth、scrollHeight、scrollTop、scrollLeft

width、height

getComputedStyle()

getBoundingClientRect()

重绘

当节点需要更改外观而不会影响布局的,比如改变 color、background-color、visibility等就叫称为重绘。

触发重绘的属性

关键词: 不影响布局

比如: color, border-style, visibility, background, outline, box-shadow...

重绘回流的优化

CSS 方面

1、避免使用 table布局, 因为 table 布局需要多次计算元素宽度。
2、动画速度不要调的太快, 一些复杂的动画让其绝对定位脱离文档流。
3、避免使用CSS表达式, 如: calc 计算属性。

JS 方面

1、避免频繁操作样式, 最好用一个 className 一次操作完。
2、不要频繁读取元素宽高和距离等属性, 尽可能用变量缓存起来。
3、如果需要频繁操作 DOM 节点, 可以先设为display: none; 4、操作完后再设回去(将回流次数减到最少)。

如果您觉得我的文章有用,欢迎点赞和关注,也欢迎光临我的个人博客github.com/BokFang