应优先使用 transform 和 opacity 替代 top/left、display 等触发重排的属性,批量变更用 className 而非 style,resize/scroll 事件需节流并配合 requestAnimationFrame,读取布局信息须集中前置、写操作统一后置。

频繁重绘本身不致命,但常伴随重排发生;真正要防的是「重排+重绘」连锁反应——尤其是响应式场景下 resize、滚动、媒体查询切换时。
哪些操作会意外触发重排,进而连带重绘
很多人以为只改颜色、透明度就安全,但实际只要涉及以下任一行为,就可能触发重排(从而强制重绘):
-
top、left、width、height、margin、padding等布局属性被 JS 动态修改 - 读取
offsetTop、clientWidth、getBoundingClientRect()之前,已有未 flush 的样式变更 - 在
resize或scroll回调里直接写el.style.left = x + 'px',且没节流 - 用
display: none切换显隐——它会移出文档流,导致父容器重排
用 transform 和 opacity 替代传统位移与显隐
这是最直接有效的规避手段:它们只走合成层,不改变文档流,也不影响其他元素计算。
- 位移优先用
transform: translateX(100px),而不是left: 100px - 显隐用
opacity: 0+pointer-events: none,比display: none或visibility: hidden更可控(后者仍占位,但opacity不触发重排) - 动画中避免混用
transform和top/left——哪怕只在一个元素上,浏览器也可能降级到软件渲染 - 如果必须用
position: fixed做响应式定位,确保它不依赖父容器尺寸计算,否则 media query 切换时仍可能重排
批量样式变更必须走 className,别碰 style
每次写 el.style.color = 'red' 都可能触发同步重排,尤其当元素有浮动、flex 子项或百分比宽高时。
立即学习“前端免费学习笔记(深入)”;
- 把响应式状态映射为 CSS 类,比如
.mobile-nav-open、.tablet-grid-2 - 用
element.classList.toggle()切换,而不是循环设style属性 - 动态插入规则?用
CSSStyleSheet.insertRule(),别拼<style>标签——前者注册即止,不立即计算 - 需要临时高亮一组元素?提前定义好
.highlight类,运行时只操作类名
resize 和 scroll 事件里最容易踩坑
这两个事件每秒可触发数十次,不做处理几乎必然引发卡顿。
- 必须加节流(
throttle),推荐用requestAnimationFrame包裹,而不是简单setTimeout - 读取布局信息(如
el.offsetWidth)一定要集中前置,写操作统一后置——杜绝“读-写-读”交错 - 不要在回调里直接修改多个元素的
style,改用一个开关类控制整组行为 - 考虑用
ResizeObserver替代window.resize监听,它只在目标元素尺寸变化时触发,更精准
真正难的不是知道该用 transform,而是所有响应式逻辑里——包括第三方库的动画、UI 框架的折叠菜单、甚至 CSS-in-JS 的 media query 注入——都得统一约束在合成层路径上。漏掉一处,整条链路就退回重排。


















