Web Worker 与 JavaScript 沙箱

281 阅读3分钟

我们把从查询接口获取到的数据,格式化的过程(数据格式化这个过程可能会涉及一些比较大的计算,因此我们选择将它拆出来放在一个单独web worker线程中,减少对主线程造成影响),放在web worker中进行。

而这些性能优化的需求在前端侧一方面涉及频率低,另一方面也能通过微任务或服务端侧处理来解决,它并不能像 Web Socket 这种技术为前端页面下的轮询场景的优化能带来质的改变。

异步任务与Web Worker的关系

异步任务就没必要放 Worker 子线程中运行了,因为按照 JS 运行机制,异步任务本身就不阻塞主线程的执行,等异步任务执行完之后,它就会被塞进异步任务队列,待主线程空闲之后,再依次执行异步任务队列。具体的执行机制可以查阅我这一篇文章 一文搞懂JS系列(六)之微任务与宏任务,Event Loop 参考:developer.mozilla.org/zh-CN/docs/…

直至 2019 年爆火的微前端架构的出现,基于微应用间 JavaScript 沙箱隔离的需求,Web Worker 才得以重新从边缘化的位置跃入到我的中心视野。根据我已经了解到的 Web Worker 的相关知识,我知道了 Web Worker 是工作在一个独立子线程下(虽然这个子线程比起 Java 等编译型语言的子线程实现得还有点弱,如无法加锁等),线程之间自带隔离的特性,那基于这种「物理」性的隔离,能不能实现 JavaScript 运行时的隔离呢?

当我们作为前端开发人员较长一段时间后,我们很轻易地就能想到在同一个页面下,使用沙箱需求的诸多应用场景,譬如:

  1. 执行从不受信的源获取到的第三方 JavaScript 代码时(比如引入插件、处理 jsonp 请求回来的数据等)。
  2. 在线代码编辑器场景(比如著名的 codesandbox)。
  3. 使用服务端渲染方案。
  4. 模板字符串中的表达式的计算。

这里我们先回到开头,先将前提假设在我正在面对的微前端架构设计下。在微前端架构(推荐文章 Thinking in Microfrontend拥抱云时代的前端开发架构——微前端 等)中,其最关键的一个设计便是各个子应用间的调度实现以及其运行态的维护,而运行时各子应用使用全局事件监听、使全局 CSS 样式生效等常见的需求在多个子应用切换时便会成为一种污染性的副作用,为了解决这些副作用,后来出现的很多微前端架构(如 乾坤)有着各种各样的实现。譬如 CSS 隔离中常见的命名空间前缀、Shadow DOM、 乾坤 sandbox css 的运行时动态增删等,都有着确实行之有效的具体实践,而这里最麻烦棘手的,还是微应用间的 JavaScript 的沙箱隔离。 在微前端架构中,JavaScript 沙箱隔离需要解决如下几个问题:

  1. 挂在 window 上的全局方法/变量(如 setTimeout、滚动等全局事件监听等)在子应用切换时的清理和还原。
  2. Cookie、LocalStorage 等的读写安全策略限制。
  3. 各子应用独立路由的实现。
  4. 多个微应用共存时相互独立的实现。