transition: left 必然触发重排,因浏览器必须重新计算元素在文档流中的位置、尺寸、换行及文本包裹等,遍历更新整个 layout 树,全程在主线程执行;而 transition: transform 仅走 GPU 合成层,不触发布局与重绘,性能更优。

为什么 transition: left 必然触发重排(reflow)
浏览器对 left 的修改必须重新计算元素在文档流中的位置、尺寸、换行、文本包裹等,整个 layout 树都要遍历更新。这个过程完全在主线程执行,一次 getBoundingClientRect() 或 offsetTop 读取就可能强制同步触发布局计算。低端安卓 WebView(尤其是 Android 5–7)单次重排耗时常达 3–8ms,远超 16.67ms 的帧间隔底线。
transition: left 和 transition: transform 渲染路径完全不同
前者走 Layout → Paint → Composite 全链路,CPU 全包;后者只走 Composite 层,由 GPU 合成线程独立处理位移,不碰布局、不重绘、不阻塞主线程。
- 错:
transition: left 0.3s→ 动画全程 CPU 渲染,滚动中极易堆积帧 - 对:
transition: transform 0.3s→ 真正启用硬件加速,transform: translateX(100px)才是等效替代 - 混用即降级:哪怕只加一个
background-color到同一transition声明里,整条动画立刻退回 CPU 渲染
常见踩坑场景与对应解法
很多“不动”或“跳变”的现象,其实不是写法错,而是依赖条件没满足:
- 没设
position: relative或absolute——left对非定位元素无效,transition 不会启动 - 初始
left值未显式声明(比如靠默认值或继承)—— 浏览器无法插值,直接跳变 - 在
display: none元素上试left动画 —— 它不参与渲染,transition 无从触发 - JS 中改
el.style.left后立刻读el.offsetWidth—— 强制同步 layout,滚动中一卡一卡
为什么不能靠 will-change: left 救?
will-change 对非合成属性无效。浏览器只对 transform 和 opacity 提前建图层,设 will-change: left 等于什么都没做,还可能干扰渲染器判断。
立即学习“前端免费学习笔记(深入)”;
真正要动的,是把逻辑从「改布局属性」转向「只改合成属性」——这不是兼容性妥协,而是现代渲染管线的基本约束。哪怕 IE10+ 都支持 transform 过渡,行为比 left 更可预测,也更省资源。


















