requestAnimationFrame、requestIdleCallback、setTimeout区别

630 阅读2分钟

requestAnimationFrame

  • 理解:在下一次重绘之前调用指定的回调函数
  • 作用:避免浏览器在不必要的时间内执行更新,从而提高性能和效果
  • 原理:requestAnimationFrame 会根据显示器的刷新频率进行调度,通常是每秒60次(60帧/秒),这样可以确保在最佳时机更新屏幕
  • 用途:执行动画时减少卡顿 或 其他需要高性能更新的操作
  • 使用
const element = document.getElementById('animated-element');
let position = 0; // 初始位置

function animate() {
  position += 1; // 每帧向右移动1像素
  element.style.left = position + 'px';

  if (position < 200) { // 定义动画结束条件
    requestAnimationFrame(animate);  // 继续下一帧动画
  }
}

requestAnimationFrame(animate); // 开始执行动画

requestIdleCallback

  • 理解:在浏览器空闲时执行回调函数
  • 作用:在浏览器的主线程空闲时执行非关键任务,以避免影响用户界面的响应性能
  • 原理:requestIdleCallback 会在浏览器执行主要工作之后调用回调函数,并尽量在空闲时间内执行
  • 用途:利用闲暇时间执行一些耗时较长的计算、数据处理或其他非关键操作
  • 使用
// 定义一个任务队列
const tasks = [  { id: 1, name: 'Task 1', duration: 1000 },  { id: 2, name: 'Task 2', duration: 2000 },  { id: 3, name: 'Task 3', duration: 1500 }];

function processTask(task) {
  console.log(`Processing task ${task.id} - ${task.name}`);
  const startTime = performance.now();

  // 模拟耗时操作
  while (performance.now() - startTime < task.duration) {
    // 执行一些计算密集型的操作
  }

  console.log(`Task ${task.id} - ${task.name} completed`);
}

function work(deadline) {
  while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0) {
    const task = tasks.shift();
    processTask(task);
  }

  if (tasks.length > 0) {
    requestIdleCallback(work);
  }
}

requestIdleCallback(work);

setTimeout

  • 理解:在指定的延迟时间后执行回调函数
  • 作用:将定时器中的回调函数添加到事件队列中,并在指定的延迟时间后执行
  • 注意:setTimeout 的延迟时间是相对的,表示至少要等待多长时间才能执行回调函数,这个时间可能会受到其他任务的影响,导致时间不精确
  • 用途:定时器,定时回调
  • 使用
setTimeout(function() {
  // 延迟1秒后执行
  console.log('timer expired');
}, 1000);

总结

  • requestAnimationFrame 适用于需要高性能动画或更新的操作
  • requestIdleCallback 适用于在浏览器空闲时执行非关键任务
  • setTimeout 用于在指定的延迟时间后执行回调函数