WebWorker Caveats

Web worker是一项相当成熟的技术了,之前踩过的坑有这些:

无法访问DOM相关的API

这个限制非常影响WebWorker的实用性,对于很多人来说,如果可以在Worker里面有DOM(即使是虚拟DOM),就可以把一些运算密集型的操作放在虚拟DOM中。然而,现在已知的解决方案中,并没有典型的用例。 但是,Chrome 69+ 把一项叫做OffscreenCanvas的技术从flagged变成了shipped。这项技术可以让用户可以利用其它线程来访问CanvasContext,虽然以前似乎可以通过把一整个ctx传进去,但是估计什么操作都无法使用。这也解决了传统的CreateElement无法在Worker中调用的问题。目前来看caniuse 40%+ 指日可待,也可以准备一些polyfill。

postMessage方式非常尴尬

Worker这种API估计是受到了Go Channel的影响,使用了消息机制避免各种锁,同步,异步的问题。这样的好处在于不需要对数据的唯一性进行保证,如果结合immutable的设计模式,还可以进一步提高可用性。然而不能共用资源也代表了不能使用一些很常用的锁机制,就是concurrent基本变成不可能。 所以,针对这样的情况,建议是将运算复杂性的模块分割成Web Worker(真的做得到的其实不多),然后尽量保证各个模块之间没有太多的耦合度。

必须分割成额外的JS文件

这个也是API设计的坑,它不可以像一些inline的方式(似乎可以,只是非常复杂)做直接的内联异步。这样进一步提高了开发的门槛。对于使用了Webpack的项目来说,可以使用worker-loader解决这种问题。如果以后可以做到直接匿名函数worker,估计实用性可以进一步提高。

Typescript中与DOM的API完全不兼容

如果使用了Typescript,就一定要分割tsconfig.json,否则会在Typescript编译的时候,遇到postMessage函数签名不一致的问题。这个应该算是TS的锅,只能说有得必有失,现在的解决方案是使用Include引入另外的tsconfig.json,然后再子目录中编写worker。