行业资讯

重排与重绘:前端性能的两个词

发布时间:2026/8/20 11:50:47
重排与重绘:前端性能的两个词 重排reflow / layout与重绘repaint是浏览器把 DOM/CSS 变成屏幕像素时的两段常见工作。性能讨论里这两个词出现频率极高也极容易被混用。有人改个颜色就说「触发重排」有人把所有卡顿都归咎于「重绘太多」。分清以后优化才有靶子。一、先说一个具体麻烦一段列表滚动时卡顿。你加了阴影、改了颜色又用 JS 读offsetHeight做计算。若分不清重排与重绘你会随机删样式或随机加will-change像在碰运气。更有用的问法是1我是否在逼浏览器重新算几何2还是只需要重新画像素3是否在读布局结果造成强制同步布局二、两个词分别指什么浏览器渲染管线可以简化成A算样式BLayout重排算元素几何——大小、位置CPaint重绘把视觉效果画成图层上的像素DComposite合成图层拼到屏幕动画常希望主要发生在这里所谓重排重点是几何可能变了后面的 paint 往往也要跟着来。所谓重绘重点是外观变了但几何可能不变例如只改颜色。不是每次样式变化都同等代价也不是「重绘一定比重排便宜到可以无视」。但改几何通常更重这个直觉很管用。三、什么容易触发重排什么可能只重绘更常牵涉重排的示例非完整表1改width/height/padding/margin/border2改字体大小、文字内容导致换行变化3显示/隐藏若影响占用如display4读写布局信息offsetTop、getBoundingClientRect()、clientWidth等更常「主要是重绘」的在几何不变时1color、background-color2部分阴影、轮廓变化仍可能不便宜但不一定先重算整树几何transform/opacity的动画现代浏览器常尽量走合成层避免每帧大布局。这是「为什么动画偏好 transform」的通俗原因。细节因浏览器而异但方向正确。四、强制同步布局隐藏的性能坑典型反模式在循环里又写样式又读布局。for(consteloflist){el.style.width100px// 写consthel.offsetHeight// 读可能被迫立刻 layoutdoSomething(h)}上面代码中浏览器无法把多次写合并后再算只能穿插同步布局成本被放大。这叫强制同步布局forced synchronous layout一类问题。更稳的节奏是先读后写或批量读、批量写避免交错。constheightslist.map((el)el.offsetHeight)// 先读完list.forEach((el,i){el.style.heightheights[i]10px// 再写})上面代码中读取集中写入集中给浏览器合并计算的机会。五、优化时怎么用这两个词1先用 Performance / 性能面板看是 Layout 多还是 Paint 多不要猜2动画优先transform/opacity少每帧改宽高3列表虚拟化减少 DOM 数量比纠结单次重绘更有效4读布局缓存结果避免滚动监听里疯狂getBoundingClientRect5CSS 选择器与层级很深时也会让样式计算变贵——那是上游步骤但常和卡顿一起出现重排、重绘是诊断词汇不是宗教。目标是减少不必要的工作不是消灭一切 paint。六、常见误区1改任何 CSS 都叫重排不准确先问是否影响几何。2will-change: everything当加速器可能浪费内存用完应撤。3只看 FPS不看主线程里 Layout 火焰图会优化错层。4用display: none与visibility: hidden当一回事前者通常更影响布局流后者占位不同。5把合成当成永远免费层过多也有代价。七、小结重排关心几何有没有重算重绘关心像素有没有重画。几何变化往往更贵颜色等外观变化可能只走重绘读写布局交错会逼出强制同步布局。把两个词分清前端性能讨论才不会一直在「感觉卡」上空转。完