从setTimeout到requestAnimationFrame:前端动画性能优化

Sarah Wong | 2026-08-07T12:47:00 | JavaScript, Frontend

为什么你的CSS动画这么卡?从浏览器渲染原理到requestAnimationFrame的正确用法

# 从setTimeout到requestAnimationFrame:前端动画性能优化 最近做一个数据大屏项目,用`setTimeout`做动画卡得不行,换成`requestAnimationFrame`后丝般顺滑。 ## 为什么setTimeout会卡? `setTimeout(fn, 16)` 看似能达到60fps,但实际上它的回调时机不受浏览器渲染管控,经常在错误的时间点触发,导致掉帧。 ```javascript // 错误示范:用setTimeout做动画 function animate() { // 可能在浏览器渲染中间执行,导致布局抖动 element.style.left = (pos += 2) + 'px'; setTimeout(animate, 16); } // 正确做法:用requestAnimationFrame function animate(timestamp) { // 在浏览器下一次重绘前执行,保证60fps element.style.left = (pos += 2) + 'px'; requestAnimationFrame(animate); } requestAnimationFrame(animate); ``` ## 避免Layout Thrashing ```javascript // 这样写会导致强制同步布局,严重影响性能 items.forEach(function(item) { // 读 -> 写 -> 读 -> 写,每次写完都触发重排 var height = item.offsetHeight; // 读 item.style.height = (height * 2) + 'px'; // 写 }); // 正确:先批量读,再批量写 var heights = items.map(function(item) { return item.offsetHeight; // 批量读 }); items.forEach(function(item, i) { item.style.height = (heights[i] * 2) + 'px'; // 批量写 }); ``` 记住:**读写分离 + rAF = 丝滑动画**。另外`will-change: transform`可以提前告知浏览器创建独立图层。

← Back to Blog