代码中计算太多经常阻塞?试试它吧 - Web Worker

简介: Worker 在国内虽然一般场景下使用不多,可能没有什么存在感,但是其实是一项挺久远的技术了,只是由于一般情况下没什么必要性,属于锦上添花形 feature,很少会使用,不过在一些特殊场景下可以极大提高开发和用户体验。比如一些大型计算、数据加密等,还有诸如使用 OffscreenCanvas 来进行图片处理等。

网络异常,图片无法展示
|

什么是 Worker

Worker 是浏览器提供的一种可以创建独立后台线程运行代码的方式。

Worker 在国内虽然一般场景下使用不多,可能没有什么存在感,但是其实是一项挺久远的技术了,只是由于一般情况下没什么必要性,属于锦上添花形 feature,很少会使用,不过在一些特殊场景下可以极大提高开发和用户体验。比如一些大型计算、数据加密等,还有诸如使用 OffscreenCanvas 来进行图片处理等。

Worker 主要包括以下几种:

  1. 常见的 Web Worker,几乎所有浏览器都很早就支持,
  2. Shared Worker,一种特殊的 Web Worker,可以被多个窗口共享
  3. Service Worker,主要使用在 PWA 应用中,可以帮助构建离线应用
  4. Worklet,现在还属于实验性质,算是一种轻量级的 Web Worker,但是他可以做到访问一些渲染相关的 API

本篇先聊一聊最常用的 Web Worker

Web Worker 会在浏览器中创建一个独立的后台线程,然后执行传入的脚本,和主线程的通信主要是通过 postMessageonmessage 来实现。不过 Web Worker 中只能使用一部分的 API,如 WebSocketDate 等,而像一些 DOM 相关的 API 是无法使用的,原因很好理解,主要是为了避免线程冲突,一旦 Web Worker 线程可以操作 DOM,那诸如各种时间锁就要出现了。

创建

要创建一个 Web Worker,我们只需要建立一个独立的 worker.js 文件,然后通过 new Worker('./worker.js') 来引用即可:

const worker = new Worker('./worker.js');
复制代码

当然也可以通过 createObjectURL 来创建虚拟 url 来创建,如之前说过的 use-worker 便是使用这种方式。

通信

而通信则通过 postMessage 来完成,如主线程需要发送消息给 worker

worker.postMessage('Hello, my worker');
worker.addEventListener('message', e => {
    console.log(e);
});
复制代码

worker 文件的主体则是一个 onmessage 函数:

worker.js

onmessage = function (e) {
    console.log('Message received:', e);
    postMessage('Yes, my lord');
};
复制代码

当接收到主线程消息后,则会进入 onmessage 函数,而 workerpostMessage 不需要主体,直接调用即为发送给创建它的主线程。

销毁

要销毁一个 worker,只需要调用 terminate 方法即可:

worker.terminate();
复制代码

调用后 worker 会立刻终止并关闭,类似于操作系统中 kill 一段进程。当然 worker 也可以直接调用 close 来自行关闭:

close();
复制代码

错误处理

worker 的事件除了 message 外还包括 errormessageerrorrejectionhandledunhandledrejection,可监听对应的事件来处理对应的错误。

  • error:普通执行错误
  • messageerrorpostMessage 数据错误,一般出现在传递的数据类型不合法的情况
  • rejectionhandled:所有的 Promise reject 时触发
  • unhandledrejectionPromise reject 未处理时触发

引入外部脚本

Worker 中还可以通过 importScripts 来导入外部脚本:

importScripts('lodash.js');
复制代码

要注意 importScripts 为同步请求,会阻塞 worker 线程。如果在外部脚本中有导出,可通过挂载在全局变量中,要注意在 worker 中,全局变量需通过 self 引用,而非 window,上述的 close 一样可以通过 self 来进行调用。

importScripts('lodash.js');
_.each([1, 2, 3], n => {
    console.log(n);
});
复制代码

上述便是关于 Web Worker 的内容,下面会聊一聊其它几种 worker

相关文章
|
缓存 前端开发 JavaScript
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第10天】在Web开发中,Web Workers和Service Worker提升性能。Workers运行后台任务,防止界面冻结。Web Workers处理计算密集型任务,Service Worker则缓存资源实现离线支持。常见问题包括通信故障、资源限制、注册错误及缓存更新。通过示例代码展示了两者用法,并强调生命周期管理和错误处理的重要性。善用这些技术,可构建高性能的Web应用。
449 0
|
缓存 JavaScript 前端开发
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第6天】JavaScript的Web Workers和Service Worker增强了浏览器的性能处理和离线功能。Web Workers处理后台计算,减轻主线程压力,但通信有开销,受同源策略限制。Service Worker则能拦截网络请求,支持离线缓存和推送通知,但其生命周期和权限管理需谨慎处理。通过理解它们的工作原理和限制,开发者能创建更流畅、更健壮的Web应用。
594 0
|
缓存 JavaScript 前端开发
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第4天】JavaScript的Web Workers和Service Worker增强了Web性能。Web Workers处理后台多线程,减轻主线程负担,但通信有开销,受同源策略限制。Service Worker则用于离线缓存和推送通知,需管理其生命周期、更新策略,并确保安全。两者都带来了挑战,但也极大提升了用户体验。通过理解和优化,开发者能构建更高效、安全的Web应用。
449 2
|
移动开发 JavaScript 前端开发
Web Worker:JavaScript的后台任务解决方案
Web Worker:JavaScript的后台任务解决方案
|
移动开发 JavaScript 前端开发
【JavaScript技术专栏】Web Worker在JavaScript中的应用
【4月更文挑战第30天】HTML5的Web Worker API解决了JavaScript单线程性能瓶颈问题,允许在后台线程运行JS代码。本文介绍了Web Worker的基本概念、类型、用法和应用场景,如复杂计算、图像处理和数据同步。通过实例展示了搜索建议、游戏开发和实时数据分析等应用,并提醒注意其无法直接访问DOM、需消息传递通信以及移动端资源管理。Web Worker为前端开发提供了多线程能力,提升了Web应用性能和用户体验。
383 0
|
JavaScript 安全 数据处理
Web Worker:让网页飞起来的幕后英雄(下)
Web Worker:让网页飞起来的幕后英雄(下)
Web Worker:让网页飞起来的幕后英雄(下)
|
缓存 编解码 数据处理
Web Worker:让网页飞起来的幕后英雄(上)
Web Worker:让网页飞起来的幕后英雄(上)
Web Worker:让网页飞起来的幕后英雄(上)
|
Web App开发 移动开发 JavaScript
web worker详解
web worker详解
517 0
vite环境引入web worker方法
在 vite 环境中使用 web worker 时,如果遇到生产环境中 worker.js 文件的 MIME 类型被识别为 text/html,导致报错无法运行的情况时,可以参考以下两种方法,原理都是避免编译时产出单独的 worker.js 文件。方法一worker文件不需要包装,引入时后缀增加 ?worker&inline,使用时直接 new ImportedWorker();self.
2018 1
|
Web App开发 JSON 前端开发
🎁🎁🎁详解 Web Worker,不再止步于会用!
前面的章节都是告诉你怎么使用Worker,并没有真正的深入Worker的原理,这一章我们就来详细的了解一下Worker的原理。
631 0
🎁🎁🎁详解 Web Worker,不再止步于会用!

热门文章

最新文章