重排(reflow)是性能瓶颈主因,需避免table、inline-block+vertical-align、浮动混用、百分比尺寸依赖父级未定死等结构;flex/grid替代时须消除尺寸依赖链;template仅省解析不防重排;class切换比内联style更高效因批量处理。

重绘(repaint)本身不改布局,但频繁触发仍会卡顿;真正要防的是“重排引发的连带重绘”——而 HTML 结构不当,正是重排的温床。
哪些 HTML 结构一写就强制重排
浏览器无法提前确定尺寸或依赖上下文计算的结构,会在 DOM 变更或样式更新时立刻触发同步重排。
-
table布局:单元格宽度需遍历整行内容+其他单元格才能算出,改任意一个<td> 就全表重排 <li> <code>display: inline-block容器 + 子元素含vertical-align:对齐逻辑依赖行高、兄弟元素基线,每次插入/显示都得回溯整行 - 浮动元素(
float: left)混用内联元素:脱离文档流后,后续元素定位必须反复重算位置 - 含
width或height为百分比、且父容器尺寸未定死的嵌套结构:浏览器无法缓存子元素几何信息,读取offsetWidth就得立刻 flush 并重排 - 用
flex时避免在子项上设width: 100%同时又设flex: 1:两者冲突,浏览器可能多算一轮主轴分配 -
grid中慎用fr单位嵌套过深(如grid-template-columns: 1fr 2fr套在另一个fr容器里):尺寸推导路径变长,resize 或 DOM 插入时重排成本上升 - 所有
flex/grid容器应显式设width和height(哪怕100%),否则父级若无固定尺寸,子项的getBoundingClientRect()仍会强制重排 - 必须用
document.importNode(template.content, true)克隆,不能直接appendChild(template)——后者会把模板节点移走,下次没得用了 - 模板里不能有
<script></script>或<style></style>,它们被忽略;事件监听器必须克隆后手动绑定 - 若模板结构含
table或inline-block + vertical-align,克隆插入后照样重排——template只省了解析,不改布局逻辑 - 服务端返回的 HTML 片段,建议先塞进临时
<template></template>元素再取.content,比直接innerHTML = str更安全(避免标签未闭合导致的隐式重排) -
el.style.color = 'red'触发样式 dirty 标记,下一次读取布局属性(如offsetHeight)就立刻重排 -
el.classList.add('highlight')不改变 DOM 结构,只影响匹配规则,浏览器可延迟到下一帧统一处理 - 多个 class 切换(如
add+remove)仍是单次操作,不会像连续赋值style.color、style.fontSize那样多次标记 - 注意:class 里若含
width、margin等触发布局的属性,依然会重排——重点是“怎么改”,不是“改什么”
用 flex 或 grid 替代旧布局时的坑
不是换标签就自动变快,关键看是否消除了“尺寸依赖链”。
template 标签不是万能的,但用对了能跳过解析阶段
<template></template> 内容不参与初始渲染,也不执行脚本、不加载图片,但它克隆后插入时,仍可能因结构问题触发重排。
为什么 class 切换比内联 style 更少重绘
内联样式修改会直接污染 element.style 对象,浏览器必须立即检查 cascade 规则是否被覆盖;而 class 是 CSSOM 层的原子切换,样式变更可批量合并。
最容易被忽略的一点:重排重绘的代价不是线性的。一次 getBoundingClientRect() 后紧跟三次 style.transform 修改,浏览器仍只重排一次;但若中间插一句 offsetTop,就变成四次。结构优化的本质,是让浏览器能“猜中你下一步要干什么”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











