无需登录 数据私有 本地保存

Web Worker计算演示 - 后台斐波那契不卡顿

10
0
0
0

Web Worker 计算演示

直观对比主线程计算与后台 Worker 计算对 UI 流畅度的影响

UI 流畅度监视器
帧间隔:16ms 最大间隔:17ms 状态:流畅
小球由 requestAnimationFrame 驱动 · 卡顿时会停顿或跳跃
F(n)
范围 30~45 · 默认40 · 越大越耗时
0.0s
主线程结果
尚未计算
Worker 结果 就绪
尚未计算
观察要点:点击主线程计算时观察上方小球是否卡顿、帧间隔是否飙升;再点击Worker计算对比——小球应始终保持流畅运动。
常见问题与知识点

Web Worker 是浏览器提供的多线程机制,允许在后台线程中运行 JavaScript 代码,不阻塞主线程(UI线程)。主线程负责渲染界面、响应用户交互;当执行大量计算(如斐波那契递归、图像处理、大数据排序)时,主线程会被占用,导致页面卡顿甚至无响应。Worker 将这些耗时任务移到后台线程执行,保证 UI 始终流畅。上方演示中,主线程计算时小球冻结正是这个问题的直观体现。

  • Dedicated Worker(专用 Worker):最常用,仅能被创建它的脚本访问,一对一通信。本演示使用的就是这种。
  • Shared Worker(共享 Worker):可被多个同源页面/脚本共享,适合跨标签页通信场景。
  • Service Worker:充当网络代理,用于离线缓存、推送通知、后台同步等,是 PWA 的核心技术。
此外还有 Audio WorkletPaint Worklet 等专用工作线程,用于特定领域。

Web Worker 运行在独立线程中,无法直接访问以下内容:
  • DOM(document、window 等不可用)
  • 父页面的全局变量
  • localStorage / sessionStorage(但可使用 IndexedDB)
通信只能通过 postMessage 传递可序列化的数据(结构化克隆算法),或使用 Transferable Objects(如 ArrayBuffer)实现零拷贝传输。Worker 内部可以使用 fetchWebSocketsetTimeout 等 API。

以下场景非常适合使用 Web Worker:
  • CPU 密集型计算:如斐波那契、素数筛选、加密解密、哈希计算
  • 大数据处理:CSV/JSON 解析、数据聚合、排序、过滤
  • 图像/视频处理:Canvas 像素操作、滤镜、压缩
  • 实时数据流:WebSocket 消息处理、传感器数据解析
  • 代码编译:如在线 IDE 的 TypeScript/WebAssembly 编译
一般原则:任何预计耗时超过 50ms 的同步操作,都应考虑放入 Worker,以保持 60fps 的流畅体验。

方式一:独立文件
// worker.js
self.onmessage = function(e) {
    const result = heavyComputation(e.data);
    self.postMessage(result);
};
// 主线程
const worker = new Worker('worker.js');
worker.onmessage = (e) => console.log('结果:', e.data);
worker.postMessage(inputData);
方式二:Blob URL(内联,如本演示)
const code = `self.onmessage=function(e){...}`;
const blob = new Blob([code], {type:'application/javascript'});
const url = URL.createObjectURL(blob);
const worker = new Worker(url);
// 使用完毕后释放
URL.revokeObjectURL(url);
可通过 worker.terminate() 立即终止 Worker。

Web Worker 拥有极佳的浏览器兼容性,所有现代浏览器(Chrome、Firefox、Safari、Edge)以及移动端浏览器(iOS Safari、Android Chrome)均完整支持。Dedicated Worker 和 Shared Worker 从 IE10+ 起就已支持。Service Worker 需要 HTTPS 环境,兼容性同样广泛。可以说,在生产环境中使用 Web Worker 已无任何障碍。

递归实现的斐波那契时间复杂度为 O(2ⁿ),计算量随 n 指数增长,能产生明显且可控的耗时(n=40 时约需数秒),非常适合演示主线程阻塞效果。迭代法时间复杂度为 O(n),即使 n=10000 也能在毫秒级完成,无法体现卡顿。实际项目中当然应使用迭代法或记忆化递归来高效计算斐波那契数列——这个演示刻意用低效算法来放大问题,帮助理解 Worker 的价值。