合理使用 requestAnimationFrame 的核心是精准控制启停、配合时间戳计算、优化 DOM 操作与 CSS 属性选择。需缓存 animationId 并显式 cancel,用 timestamp 计算 delta 保证帧率无关性,仅操作 transform/opacity 等合成属性,避免强制同步布局,节流高频事件,复用单个 rAF 回调驱动多元素,并响应系统动效偏好。

合理使用 requestAnimationFrame(rAF)做动效优化,关键不在“用了没”,而在“怎么驱动、怎么收口、怎么配合其他机制”。它不是 setTimeout 的升级版,而是浏览器渲染节奏的接入点。
用对启动与停止逻辑,避免内存泄漏和持续占用
rAF 必须配合显式的启停控制,否则回调会无限注册,占用主线程且无法释放。常见错误是只调一次 requestAnimationFrame(animate) 却不保存 ID,或忘记在退出时调用 cancelAnimationFrame。
- 始终用一个变量(如
let animationId = null)缓存上一次 rAF 返回的 ID - 动画函数内部完成更新后,再根据条件决定是否继续调用
requestAnimationFrame(animate) - 暂停或离开视口时,必须执行
cancelAnimationFrame(animationId) - 恢复动画时,重新调用
requestAnimationFrame(animate)即可,无需重置整个逻辑
用时间戳计算 delta,让动画速度不依赖帧率
rAF 回调参数自带高精度时间戳(DOMHighResTimeStamp),比 Date.now() 更可靠。直接每帧加固定值(如 x += 2)会导致 30fps 设备上动画慢一半。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 记录起始时间(
startTime)和当前帧时间(timestamp) - 用
elapsed = timestamp - startTime计算真实经过时间 - 位移/透明度等按比例更新:例如
progress = elapsed / duration - 避免在回调中重复查 DOM 或计算路径,这些应提前做好
配合 CSS 合成属性,避开强制同步布局
rAF 写动画时,只操作浏览器能硬件加速的属性,才能真正发挥性能优势。改 top/left 或频繁读取 offsetHeight 会触发强制同步布局(Layout Thrashing)。
- 优先用
transform(translateX、scale、rotate)和opacity - 给动效元素加
will-change: transform提前提示合成层创建 - 不要和 CSS
transition混用同一属性(比如 JS 改transform,又写了transition: transform 0.3s),否则可能打断过渡或跳变 - 批量读 DOM 属性放一起,写样式放一起,避免“读-写-读-写”交叉
按需分层与节流,不盲目递归驱动
rAF 不是万能开关。高频事件(如 scroll、resize)里直接调用 rAF,容易造成回调堆积;多元素动画各自注册 rAF,也会增加调度开销。
- 在滚动或尺寸变化中,用 rAF 包裹节流逻辑,而不是退回到
setTimeout - 多个元素同步动效,复用同一个 rAF 回调,在内部遍历更新状态,而非每个元素单独注册
- Canvas 动画中,用
clearRect清屏后立即重绘,避免图像叠加模糊 - 响应系统偏好,检测
matchMedia('(prefers-reduced-motion)'),必要时降帧或禁用动效
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










