yihan12 / Frontend-interview

记录一些前端面试相关题目
2 stars 0 forks source link

简要谈谈重绘和回流 #20

Open yihan12 opened 10 months ago

yihan12 commented 10 months ago

1. 浏览器渲染机制

这里重要要说两个概念,一个是Reflow,另一个是Repaint:

2. 重绘

当盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来之后,浏览器便把这些原色都按照各自的特性绘制一遍,将内容呈现在页面上。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

重绘发生在元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)

由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, color、background-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。

3. 回流

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

回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。

<body>
<div class="error">
    <h4>我的组件</h4>
    <p><strong>错误:</strong>错误的描述…</p>
    <h5>错误纠正</h5>
    <ol>
        <li>第一步</li>
        <li>第二步</li>
    </ol>
</div>
</body>

在上面的HTML片段中,对该段落(p标签)回流将会引发强烈的回流,因为它是一个子节点。这也导致了祖先的回流(div.error和body – 视浏览器而定)。此外h5和ol也会有简单的回流,因为其在DOM中在回流元素之后。大部分的回流将导致页面的重新渲染。

回流必定会发生重绘,重绘不一定会引发回流。

4. 浏览器优化

现代浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能有会影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值。

主要包括以下属性或方法:

5. 减少重绘与回流

CSS

将动画效果应用到position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择 requestAnimationFrame,详见探讨 requestAnimationFrame。

避免使用CSS表达式,可能会引发回流。

将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如will-change、video、iframe等标签,浏览器会自动将该节点变为图层。

CSS3 硬件加速(GPU加速),使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。

JavaScript