Better

Ethan的博客,欢迎访问交流

Angular 中使用 WebWorker 实践

近期项目需求中,计算量导致 ui 卡顿,决定将这部分逻辑放入 web worker 中计算,由于 TypeScript 的问题,莫名其妙的报错导致花费了一下午的时间。

Angular 中使用

在 angular8 中可以直接运行命令 ng generate webWorker my-worker 开启功能。

  • 会修改 angular 工程中部分配置:生成针对 webworker 的 tsconfig 配置
  • 生成一个 worker 工作示例

Worker 需要通过网络来加载一个脚本,如何配合 webpack 来自动化完成这件事情呢,你可以使用下面的语法,angular-cli 会自动进行代码分割

const worker = new Worker(`./my-worker.worker`, { type: `module` });

踩的坑

编译卡住

主线程中负责创建 Worker 对象的文件 A,如果 worker.js 中也 import 文件 A 中某些函数,会导致编译卡住。具体不知道是不是这个原因,但将代码拆分出来,问题也就解决了。

数据限制

还有你需要知道 web worker 中通信数据的限制,类似于网络传输中序列化与反序列化。虽然 web worker 会对 message 自动进行序列化与反序列。但你需要知道这样的后果就是,如果传递对象,会导致原型链丢失,也就是说对象中的函数会丢失,且原型链直接指向 Object。

看到这里,突然就明白了一些第三方库提供 toJSON 和 fromJSON 的目的了。所幸我的例子中,jsts 提供了 geojsonWriter 和 geojsonReader 函数,可以达到我们的目的。

变异报 require 相关错误

在修改 tsconfig 的过程中发现,导致 require 函数报错的原因是 tsconfig 的 types 字段需要包含 node

变异报类型错误

针对 worker 的 tsconfig 比较特殊,由于 web worker 不能访问 dom 元素。因此需要将 lib 中 dom 修改为 webworker。且这两者是不能同时存在的。

这里有个巨大的坑,就是我们引用的第三方库很可能引用 dom 中才有的类型声明,从而导致居多的错误。你可以设置 skipLibCheck: true 来跳过第三方库检查。



留言