Sunday面试指南

浏览器重排和重绘有什么区别?怎样减少页面卡顿?

🧑‍💻 面试官:重排和重绘有什么区别?

🙋‍♂️ 我:重排重新计算布局,重绘重新画外观。修改宽高会重排,修改颜色会重绘。

🧑‍💻 面试官:那每次写 style 后,浏览器会立刻执行一次重排吗?

🙋‍♂️ 我:应该会,否则怎么显示新的宽度?

🧑‍💻 面试官:浏览器可以延后批量处理。但如果你刚改宽度,马上又读取 offsetWidth,会发生什么?

除了区分布局和绘制,更要看浏览器能否批量工作,以及代码有没有逼它提前计算。

面试速答(60 秒版)

重排通常指重新计算元素的几何布局,重绘则是更新外观。尺寸、位置和内容变化可能触发布局;颜色等变化可能只需要绘制。部分 transform、opacity 动画在合适条件下可以主要通过合成完成,但不是无条件的免费操作。

浏览器会尽量合并更新,所以多次写样式不等于每次都立即布局。危险的是样式写入后又要求最新几何值,可能触发强制同步布局;循环中反复读写就容易形成布局抖动。

实际优化时,我会先用 Performance 找耗时,再减少不必要的 DOM 工作、组织读写顺序,并控制动画和图层。不能只凭属性名,就判断一个页面一定流畅。

布局计算几何,绘制更新外观,合成组合相应图层

知识点详解:为什么看起来很短的 DOM 循环,也会卡

布局变了,和外观变了,不是一件事

假设一张卡片从宽 200px 改成 300px,旁边和下面的内容可能需要重新安排位置。这属于几何布局变化,后面还可能产生新的绘制和合成工作。

如果只是把卡片文字从黑色改成红色,位置和尺寸未必改变,就可能主要更新绘制。浏览器可以只处理受影响的部分,不能说重排一定重算整个页面。

transform 移动元素通常不改变正常流的布局位置,因此动画更容易避开反复布局。但是否需要重新绘制、是否适合提升图层,仍受内容、实现和资源情况影响。层叠上下文也不等于 GPU 合成层。

真正容易出问题的是写完马上读

浏览器已经知道上一轮布局的结果。若没有新的相关修改,读取几何值可能直接使用已有结果。

现在咱们先修改一个盒子的宽度,再马上读取 offsetWidth。为了返回符合当前样式的值,浏览器可能不得不提前计算样式和布局。问题不是“读取尺寸必然很慢”,而是这个读取要求它在不合适的时候交作业。

如果循环里每个元素都这样做,就会反复打断原本可以合并的工作。这个现象通常叫强制同步布局或布局抖动。

把读写顺序整理好,但别偷偷改变需求

假设多个段落都要使用参考盒子的当前宽度,而且设置段落宽度不会改变这个参考值。可以先读取一次,再统一写入。

const box = document.querySelector<HTMLElement>("#reference");
const rows = document.querySelectorAll<HTMLElement>(".row");
if (box) {
  const width = box.offsetWidth;
  rows.forEach(row => { row.style.width = width + "px"; });
}

这是浏览器 DOM 示例,没有原生 Python 等价 API。代码重点是“不再每写一次就读一次”,不是说 offsetWidth 绝不能用。

但如果业务必须读取修改之后的新尺寸,就不能把读取简单移到修改之前。可以调整布局方案、把更新分阶段,或接受确实需要的一次同步测量。正确优化要保持原来的结果。

requestAnimationFrame 方便把视觉更新安排到合适时机,但它不会自动消除回调内部的读写交错。把坏循环装进它,坏循环仍然存在。

先录一次卡顿,再决定改哪里

打开 Performance,触发实际的展开、拖拽或滚动,检查脚本、样式计算、Layout、Paint 的分布和长任务。若主要时间在一个复杂计算里,换成 transform 并不能解决它。

动画也不要给所有元素长期加 will-change。图层会占用内存,准备和维护本身也有成本。只有确认需要、知道何时开始和结束时,再按实际效果使用。

优化前后应执行同一段交互,使用相近的设备与 CPU 条件,比较耗时和响应表现,并检查视觉结果有没有变化。这样才能证明是减少了工作,而不是把工作藏到了另一个阶段。

本题机制参考:MDN:浏览器渲染、web.dev:避免布局抖动。

参考尺寸不受更新影响时,可以先读取再批量写入,减少反复同步计算

面试官继续追问

重排一定导致整页重绘吗?

布局变化可能引出受影响区域的绘制与合成,但不代表每次都整页处理。浏览器可以增量更新,影响范围需要测量。

读取 offsetWidth 一定强制重排吗?

不是。已有布局有效时可以使用已有值;相关布局被修改而读取又要求最新结果时,才可能触发同步工作。

60Hz 页面每帧有 16.7ms,能全部给脚本吗?

不能。这个时间是近似整帧预算,渲染、浏览器其他工作也要占用,刷新率还可能不同。不要把 16.7ms 当固定可用脚本额度。

面试速记卡

  • 重排:重新计算位置与尺寸。
  • 重绘:更新视觉外观,不必总改变几何。
  • 强制同步布局:相关写入后要求最新几何值。
  • 优化:减少工作、组织读写,不能改变业务结果。
  • 验证:录制相同交互,检查脚本、布局与绘制实际耗时。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历