js加密之为什么要用requestAnimationFrame

67 阅读3分钟

requestAnimationFramesetTimeoutsetInterval 都是 JavaScript 中用于调度代码执行的工具,但它们在性能、适用场景和行为上有显著差异。以下是它们的详细对比:

另外如js加密后源代码丢失,可以找博主人工解密恢复源码。各位加密的时候一定要保存好自己的源代码备份好,以防丢失。


1. requestAnimationFrame

优点

  • 与浏览器刷新率同步

    • 自动匹配浏览器的刷新率(通常为 60Hz,即每 16.67ms 执行一次)。
    • 确保动画流畅,避免掉帧。
  • 高效节能

    • 当页面不可见(如切换到其他标签页)时,自动暂停执行,减少 CPU 和 GPU 的消耗。
  • 浏览器优化

    • 浏览器会优化 requestAnimationFrame 的执行,例如合并多个动画更新。

缺点

  • 无法手动控制执行频率

    • 执行频率由浏览器决定,无法像 setTimeoutsetInterval 那样手动设置时间间隔。
  • 不适合非动画任务

    • 主要用于动画场景,不适合需要固定时间间隔的任务(如轮询、定时检查等)。

适用场景

  • 动画(如 CSS 动画、Canvas 动画、WebGL 渲染)。
  • 游戏开发。
  • 任何需要与屏幕刷新同步的任务。

2. setTimeout

优点

  • 灵活控制

    • 可以手动设置延迟时间,适合需要精确控制执行时间的任务。
  • 兼容性好

    • 所有浏览器都支持,包括旧版本浏览器。

缺点

  • 时间不精确

    • 由于 JavaScript 的单线程特性,setTimeout 的实际执行时间可能会延迟,尤其是在主线程繁忙时。
  • 不适合高频任务

    • 高频调用(如每 16ms 调用一次)可能导致性能问题。
  • 无节能机制

    • 即使页面不可见,setTimeout 仍会继续执行,浪费资源。

适用场景

  • 延迟执行某些任务。
  • 简单的定时任务(如轮询、倒计时)。
  • 不需要高频率调用的场景。

3. setInterval

优点

  • 周期性执行

    • 可以按照固定的时间间隔重复执行代码。
  • 兼容性好

    • 所有浏览器都支持,包括旧版本浏览器。

缺点

  • 时间不精确

    • setTimeout 一样,实际执行时间可能会延迟。
  • 容易堆积任务

    • 如果任务的执行时间超过间隔时间,会导致任务堆积,影响性能。
  • 无节能机制

    • 即使页面不可见,setInterval 仍会继续执行,浪费资源。

适用场景

  • 需要周期性执行的任务(如轮询、定时检查)。
  • 不需要高频率调用的场景。

对比表格

特性requestAnimationFramesetTimeoutsetInterval
执行频率与浏览器刷新率同步(通常 60Hz)手动设置延迟时间手动设置间隔时间
时间精确性高,与浏览器刷新同步低,可能延迟低,可能延迟
节能机制页面不可见时自动暂停
适用场景动画、游戏等高性能需求延迟任务、简单定时任务周期性任务
任务堆积可能堆积
兼容性现代浏览器所有浏览器所有浏览器

示例对比

1. requestAnimationFrame 实现动画

function animate() {
    // 动画逻辑
    requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

2. setTimeout 实现动画

function animate() {
    // 动画逻辑
    setTimeout(animate, 16); // 模拟 60Hz
}
setTimeout(animate, 16);

3. setInterval 实现动画

function animate() {
    // 动画逻辑
}
setInterval(animate, 16); // 模拟 60Hz

总结

  • requestAnimationFrame

    • 最适合动画和高性能任务。
    • 自动同步浏览器刷新率,高效节能。
  • setTimeout

    • 适合延迟执行或低频任务。
    • 时间不精确,无节能机制。
  • setInterval

    • 适合周期性任务。
    • 时间不精确,可能导致任务堆积。

根据具体需求选择合适的工具:

  • 如果是动画或高性能任务,优先使用 requestAnimationFrame
  • 如果是简单的定时任务,可以使用 setTimeoutsetInterval