面试题答案
一键面试引起重排(reflow)的场景
- 添加或删除可见的 DOM 元素:当添加或删除元素时,页面布局需要重新计算,因为元素的存在与否会影响其他元素的位置和尺寸。
- 元素的尺寸改变:包括宽度、高度、边距、边框等改变,会使浏览器重新计算元素的位置和其他元素的布局。
- 改变字体大小:字体大小改变可能影响行高,从而影响整个文本布局,导致重排。
- 浏览器窗口尺寸改变:浏览器窗口大小变化会使页面布局重新调整以适应新的窗口尺寸。
重排优化策略
- 批量操作 DOM:
- 策略:将多次对 DOM 的操作合并成一次。例如,使用文档片段(
document.createDocumentFragment()
),先在片段上进行所有操作,最后将片段添加到 DOM 中。 - 原理:减少触发重排的次数,因为每次直接操作 DOM 都会导致重排,而操作片段不会直接影响页面布局,只有最后添加到 DOM 时才触发一次重排。
- 策略:将多次对 DOM 的操作合并成一次。例如,使用文档片段(
- 先修改样式,再应用:
- 策略:先在元素的
classList
中添加新的类,或直接设置多个样式属性,而不是一次一个地改变样式。 - 原理:浏览器会将样式的改变收集起来,最后一次性应用,减少重排次数。例如,改变元素的
width
后紧接着改变height
,如果分开操作,会触发两次重排,而合并操作只会触发一次。
- 策略:先在元素的
引起重绘(repaint)的场景
- 改变元素的颜色:如
color
、background-color
等属性的改变,只影响元素的外观,不影响布局。 - 改变元素的可见性:
visibility
属性的改变,元素从可见变为不可见或反之,会导致重绘,但不影响布局。 - 改变元素的轮廓:
outline
属性的改变,因为轮廓只绘制在元素周围,不影响布局。
重绘优化策略
- 使用 CSS 3D 变换:
- 策略:对于一些动画效果,使用
transform
和opacity
等属性,而不是改变left
、top
等会触发重排的属性。 - 原理:浏览器会将 3D 变换的元素提升到单独的合成层,这些操作不会影响其他元素的布局,且合成层的绘制可以独立于其他层,从而减少重绘的范围。
- 策略:对于一些动画效果,使用
- 避免使用
filter
:- 策略:尽量不使用或减少使用 CSS
filter
属性,尤其是在动画中。 - 原理:
filter
通常会触发重绘,而且计算成本较高,会影响性能。如果必须使用,可考虑在动画结束后再应用。
- 策略:尽量不使用或减少使用 CSS
通过 Chrome DevTools 检测和分析重排与重绘对页面性能的影响
- Performance 面板:
- 操作:打开 Chrome DevTools,切换到 Performance 面板,点击录制按钮,然后在页面上进行各种操作(如滚动、点击等),完成后停止录制。在时间轴中,可以看到“Layout”事件表示重排,“Paint”事件表示重绘。通过分析这些事件的时长和发生频率,可以了解重排和重绘对性能的影响。
- 原理:Chrome DevTools 会记录页面在运行过程中的各种事件,包括重排和重绘事件,通过可视化的方式展示它们的发生时间和持续时间,帮助开发者定位性能瓶颈。
- Layers 面板:
- 操作:打开 Chrome DevTools,切换到 Layers 面板。这里可以查看页面的层结构,了解哪些元素在单独的层上,以及层的合成情况。如果某个元素频繁触发重排或重绘,可以检查它是否被提升到单独的层,以及层的合成是否合理。
- 原理:通过查看层的信息,可以优化页面的层结构,减少重排和重绘的范围,例如将一些频繁变化的元素提升到单独的层,避免影响其他元素的绘制。