JavaScript动画应优先使用requestAnimationFrame驱动,它对齐屏幕刷新率、自动暂停省电;避免setTimeout/setInterval和强制同步布局;推荐transform/opacity动画,结合缓动函数实现状态插值;CSS适合固定动效,JS适合交互式动画,可借助Web Animations API桥接。

JavaScript 实现动画不是靠“写个教程”就能跑起来的,而是取决于你用什么机制驱动、怎么控制时间、以及是否绕过了浏览器渲染瓶颈。直接上 setTimeout 或硬写 for 循环递增样式,大概率卡顿、掉帧、响应迟钝。
用 requestAnimationFrame 而不是 setTimeout 或 setInterval
浏览器在每次重绘前会触发 requestAnimationFrame,它自动对齐屏幕刷新率(通常是 60fps),且在标签页不可见时自动暂停,省电又稳定。而 setTimeout(fn, 16) 只是“尽力而为”,实际执行时机不可控,容易累积延迟或跳帧。
实操建议:
- 永远把动画逻辑封装在
requestAnimationFrame回调里,不要用setInterval模拟帧循环 - 如果需要暂停/继续,保存
requestId并用cancelAnimationFrame控制 - 避免在回调中做大量计算或 DOM 查询——把计算提前,只留渲染操作
动画的本质是「状态插值 + 定时更新」
所谓“动起来”,就是让某个属性(比如 element.style.left 或 transform)从起始值,按时间函数(ease-in、linear 等)逐步过渡到目标值。关键不在“怎么变”,而在“每帧变多少”。
立即学习“Java免费学习笔记(深入)”;
实操建议:
- 优先用
transform和opacity动画,它们走合成层,不触发 layout/paint,性能最好 - 别直接改
top/left,那会强制同步布局(forced synchronous layout),严重拖慢 - 手写插值时,用
startTime和当前performance.now()算出已过时间比,再代入缓动函数(如t => t * t是 ease-in-quad)
CSS 动画和 JS 动画不是二选一,而是分工问题
纯 CSS 动画(@keyframes + animation)启动快、声明式、省 JS 执行开销,但无法动态控制中间状态、不能响应滚动或鼠标位置实时变化。JS 动画灵活,但写多了容易失控。
实操建议:
- 固定时长、无需交互的入场/退出动效,用 CSS;需要拖拽跟随、视差、滚动触发动画的,用 JS
- 可以用
element.animate()(Web Animations API)桥接两者:它返回Animation对象,支持play()/pause()/currentTime,比纯 CSS 更可控 - 注意兼容性:
element.animate()在 Safari 上直到较新版本才稳定,旧环境仍需降级到requestAnimationFrame手写
真正难的不是让元素动起来,而是判断该不该动、什么时候停、动完后如何释放资源。比如一个无限滚动列表里的卡片入场动画,没做节流或销毁,几十个同时运行就会明显卡顿——这时候原理都对,错在没管生命周期。











