☕ 404 星球 · 前端晨间广播 | 2025-10-29
1️⃣ React 19 稳定版发布,并发特性默认开启
- • 全新
use()Hook 支持在组件顶层读取 Promise & Context - • 自动批处理范围扩大至
setTimeout/ 事件处理器,零配置性能提升 8~12% - • 官方兼容检查工具
react-compat-19一键扫描废弃 API,CI 友好
2️⃣ TypeScript 5.7 带来“类型收窄新魔法”
- •
satisfies运算符增强:可在泛型内部直接约束字面量类型,减少 30% 冗余代码 - • 性能优化:增量编译缓存命中率提升,大型单体仓库编译时间再降 18%
- • 即刻通过
npm i typescript@rc尝鲜,正式版 11 月中旬落地
3️⃣ ECMAScript 2026 草案:管道运算符 |> 进入 Stage-3
- • 写法:
value |> fn1 |> fn2;Babel / SWC 已同步实现 - • 配合部分应用语法
foo(?),可将嵌套回调改写为“链式”平面结构,降低心智负担 - • Chrome 136 与 Firefox 128 预计 2026 Q1 首发货真价实原生支持
4️⃣ Vite 6 RC 2 发布,默认启用 Rolldown 打包核心
- • 冷启动速度再砍 35%,大型项目 (
>5k模块) HMR 稳定在 80 ms 内 - • 支持“增量产物签名”,实现多实例部署秒级回滚
- • 配置项 100% 向下兼容,官方提供
vite-5to6一键迁移 CLI
5️⃣ CSS @layer 现在可以“动态命名”
- • Chrome 135 开启 Origin Trial:允许
layer-name: var(--foo)运行时切换 - • 与
prefers-color-scheme联动,可一句代码完成“亮色/暗色”样式层重排 - • 预计 2026 Q3 进入稳定通道,设计系统同学可以提前上车
— ☕️🌅 —
一、前言
在前端开发领域,实现流畅的动画效果对于提升用户体验至关重要。然而,动画的实现方式多种多样,如何选择合适的动画方法,是摆在开发者面前的一个重要问题。requestAnimationFrame 和定时器(setTimeout、setInterval)都是常用的动画实现手段,但它们在原理、性能、适用场景等方面存在显著差异。本文将深入剖析 requestAnimationFrame 与定时器的对比,帮助开发者做出更明智的选择。
二、requestAnimationFrame 简介
基本概念
requestAnimationFrame 是浏览器提供的一个专门用于动画的 API,它告诉浏览器在下次重绘之前执行回调函数,以更新动画。其基本语法如下:
let requestId = requestAnimationFrame(callback);
- •
callback:一个函数,浏览器在下次重绘之前会调用该函数。该函数接收一个参数,表示当前时间(以毫秒为单位)。 - •
requestId:一个整数,唯一标识了该次请求,可用于取消动画。
工作原理
浏览器在运行时,会维护一个事件循环,处理各种任务,如 JavaScript 执行、DOM 更新、页面重绘等。requestAnimationFrame 的回调函数会被放入浏览器的动画帧队列中,在事件循环的重绘阶段执行。具体来说,浏览器在每次重绘前,会检查动画帧队列,依次执行其中的回调函数,然后执行重绘操作,更新页面内容。
优点
-
- 与浏览器重绘同步:
requestAnimationFrame的回调函数在浏览器重绘之前执行,能够确保动画的更新与页面重绘同步,避免不必要的重绘,提高动画性能。
- 与浏览器重绘同步:
-
- 优化的性能表现:浏览器会对
requestAnimationFrame进行优化,当页面不可见或处于后台时,浏览器会暂停动画,节省资源消耗。
- 优化的性能表现:浏览器会对
-
- 流畅的动画效果:由于其与浏览器重绘同步,动画的帧率能够与浏览器的刷新率相匹配,通常为 60Hz,从而实现流畅的动画效果。
局限性
-
- 兼容性问题:在一些老版本的浏览器中,
requestAnimationFrame可能不被支持,需要进行兼容性处理。
- 兼容性问题:在一些老版本的浏览器中,
-
- 无法控制执行频率:
requestAnimationFrame的回调函数执行频率由浏览器决定,无法像定时器那样精确控制执行间隔。
- 无法控制执行频率:
三、定时器简介
基本概念
定时器主要通过 setTimeout 和 setInterval 两个函数实现,它们可以设置在特定的时间间隔后执行代码。
-
•
setTimeout:设置一个定时器,在指定的延迟后执行一次代码。let timeoutId = setTimeout(function, delay); -
•
setInterval:设置一个定时器,按照指定的时间间隔周期性地执行代码。let intervalId = setInterval(function, delay);
工作原理
定时器会在设定的延迟时间后将回调函数放入 JavaScript 执行队列中,等待事件循环处理。然而,由于 JavaScript 的单线程特性,如果当前执行栈中有其他任务在执行,定时器的回调函数可能需要等待更长时间才能执行。
优点
-
- 简单易用:定时器的使用方式简单直观,易于理解和实现。
-
- 控制执行频率:可以精确设置执行间隔,适用于一些需要固定频率执行的场景。
局限性
-
- 性能问题:如果定时器的回调函数执行时间过长,会阻塞后续代码的执行,影响页面的响应性能。
-
- 无法保证执行间隔:由于 JavaScript 的单线程特性,定时器的实际执行间隔可能会比设定的延迟时间长,导致动画不流畅。
-
- 缺乏优化:浏览器不会对定时器进行特殊优化,即使页面不可见,定时器仍会继续执行,造成资源浪费。
四、requestAnimationFrame 与定时器的对比
性能对比
- •
requestAnimationFrame:与浏览器重绘同步,性能更优,能够实现流畅的动画效果,且在页面不可见时会暂停,节省资源。 - • 定时器:可能因 JavaScript 执行队列的阻塞导致实际执行间隔不准确,影响动画性能,且无法像
requestAnimationFrame那样进行优化。
适用场景对比
- •
requestAnimationFrame:适用于大多数动画场景,尤其是需要流畅动画效果的交互式动画,如游戏、复杂动画等。 - • 定时器:适用于一些简单的、对动画流畅度要求不高的场景,或者需要精确控制执行频率的非动画任务,如定期发送请求、倒计时等。
代码示例对比
使用 requestAnimationFrame 实现动画
let start = null;
const element = document.getElementById('animated-element');
function animate(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;
// 假设动画持续2秒
const progress = Math.min(elapsed / 2000, 1);
element.style.transform = `translateX(${progress * 100}px)`;
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
使用 setInterval 实现动画
let start = null;
const element = document.getElementById('animated-element');
const duration = 2000; // 动画持续时间
const startTime = Date.now();
const intervalId = setInterval(() => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
element.style.transform = `translateX(${progress * 100}px)`;
if (progress >= 1) {
clearInterval(intervalId);
}
}, 16); // 约60帧每秒
在上述示例中,使用 requestAnimationFrame 的动画更加流畅,且浏览器会进行优化,而使用 setInterval 的动画可能因各种因素出现卡顿。
五、最佳实践建议
-
- 优先使用
requestAnimationFrame:在实现动画时,应优先考虑使用requestAnimationFrame,以获得更好的性能和流畅度。
- 优先使用
-
- 合理处理兼容性:对于不支持
requestAnimationFrame的浏览器,可以使用setTimeout进行降级处理,但要确保动画的流畅性。
- 合理处理兼容性:对于不支持
-
- 避免在动画回调中执行复杂操作:无论是使用
requestAnimationFrame还是定时器,都应避免在回调函数中执行复杂的计算或 DOM 操作,以免影响动画性能。
- 避免在动画回调中执行复杂操作:无论是使用
-
- 使用
cancelAnimationFrame取消动画:当动画不再需要时,应及时使用cancelAnimationFrame取消动画,释放资源。
- 使用
六、结语
requestAnimationFrame 和定时器各有优缺点,在动画实现中,requestAnimationFrame 通常能提供更好的性能和流畅度,是现代前端动画的首选方法。然而,定时器在一些特定场景下仍有其应用价值。开发者应根据具体需求和场景,合理选择动画实现方式,以达到最佳的用户体验。通过深入理解两者的差异,我们能够更加高效地开发出高性能、高质量的动画效果,为用户带来更加出色的视觉体验。