贝利信息

javascript动画怎样实现平滑效果?【教程】

日期:2026-01-23 00:00 / 作者:狼影
应使用 requestAnimationFrame 替代 setTimeout/setInterval 实现动画,因其能精准对齐设备刷新率、自动暂停省电、需递归调用;配合缓动函数、避免布局抖动、统一 transform 操作及妥善清理动画状态,才能保障流畅 60fps。

requestAnimationFrame 替代 setTimeoutsetInterval

浏览器默认以约 60fps 渲染画面,requestAnimationFrame 能精准对齐这一节奏,而 setTimeout 的执行时机不可控,容易跳帧或卡顿。

常见错误是写成:setInterval(() => { update(); render(); }, 16) —— 实际延迟受 JS 主线程阻塞影响,16ms 往往无法保证。

动画值要用缓动函数(easing),别直接线性插值

人眼对匀速运动敏感,会觉得“机械”;真实物理运动多有加速度变化。直接用 (end - start) * progress 是线性插值,平滑度差。

推荐从简单起步:easeOutQuad(二次缓出)或 easeInOutCubic,比 CSS 的 ease 更可控。

避免强制同步布局(Layout Thrashing)

在单帧内反复读写 DOM 几何属性(如 offsetTopgetBoundingClientRect()),会触发浏览器反复重排重绘,直接拖垮帧率。

典型错误模式:el.style.left = el.offsetLeft + 1 + 'px'; —— 每次 offsetLeft 都强制同步计算布局。

动画状态要可中断、可复位,别堆叠定时器

用户快速连续触发动画(比如 hover 多次),若没清理前一个 requestAnimationFrame ID,会导致多个动画逻辑并发执行,数值错乱、CPU 升高。

关键不是“怎么开始”,而是“怎么干净地结束”。

平滑不是靠堆参数或加帧率,而是让每一帧的计算轻量、读写分离、状态可控。最容易被忽略的是 layout thrashing —— 它不会报错,但会让 60fps 的动画掉到 30fps 以下,且很难定位。