web worker 脚本加载有四种演进式方式:1. importscripts(同步、全局污染、兼容性最强);2. type="module"+static import(模块化、作用域隔离);3. 动态 import()(按需异步加载);4. sharedarraybuffer+自定义加载器(高性能定制方案)。

在 Web Worker 多线程环境中,脚本加载方式并非只有 importScripts 一种,而是随着浏览器能力演进,逐步形成了四种典型运行方式:传统 importScripts、ES 模块 import、动态 import()(模块上下文内)、以及基于 SharedArrayBuffer + 自定义加载器的轻量方案。它们不是并列替代关系,而是按兼容性、模块化程度和执行模型分层演进。
importScripts:同步加载,全局污染,但最稳
这是 Web Worker 最原始、最广泛兼容的脚本引入方式。它会阻塞 Worker 线程,直到所有脚本下载、解析、执行完毕,后续代码才继续运行。所有导入脚本中的变量(如 _、Lodash)直接挂载到 Worker 全局作用域,可直接使用。
- 支持相对路径(相对于 worker 文件)、绝对 URL(需同源或开启 CORS)和 data URL
- 不支持 ES 模块语法(
export/import),也不返回 Promise - 适合快速接入已有的 UMD/Global 脚本(如 moment.js、lodash.min.js)
- 嵌套调用合法:
t1.js中再调用importScripts('t2.js'),仍保持同步顺序执行
type="module" + static import:模块化起点,作用域隔离
当创建 Worker 时指定 { type: 'module' },即可启用 ES 模块支持。此时可在 worker 文件中使用静态 import 语句,如 import { add } from './math.js'。模块被异步解析,但整个 Worker 启动会等待模块图加载完成(类似 script type="module" 的行为)。
- 导入的模块拥有独立作用域,不会污染全局,更利于维护和测试
- 支持顶层
await(在模块作用域内),可配合import.meta.url构造动态路径 - 必须使用 HTTPS 或 localhost,不支持 file:// 协议
- 无法混用
importScripts和模块import—— 二者属于不同加载机制,不可共存于同一 Worker 实例
动态 import():按需加载,真正异步
在 type="module" 的 Worker 中,可使用 import() 表达式实现运行时条件加载或拆包逻辑。它返回 Promise,不阻塞线程,适合延迟加载非核心功能(如某类加密算法、区域化工具集)。
- 例如:
const { parser } = await import('./parsers/json-parser.js'); - 支持字符串模板路径(只要最终是有效 URL),可用于构建插件式架构
- 注意:每次
import()都会触发完整模块解析流程,重复调用相同路径仍会复用已解析模块(符合 ES 模块规范) - 不能在非模块 Worker 中使用,否则报
Dynamic imports are only supported in modules
自定义加载器 + SharedArrayBuffer(进阶场景)
对于极致性能要求或特殊部署环境(如离线 PWA、微前端沙箱),可绕过浏览器默认加载机制:主线程预先将压缩后的脚本内容通过 postMessage 发送至 Worker,并利用 SharedArrayBuffer + TextEncoder 高效传输;Worker 收到后用 eval 或 Function 构造器执行(需确保来源可信),或借助 WebAssembly.instantiateStreaming 加载 wasm 模块。
- 规避了网络请求开销和 CORS 限制,适合预置逻辑或热更新场景
- 需要手动管理依赖、缓存、错误边界,开发成本高,仅建议在框架层封装使用
- Chrome/Firefox 已支持
createImageBitmap等 API 直接从内存构造资源,为该模式提供新可能 - 注意:
eval执行远程脚本有严重安全风险,生产环境必须配合 Subresource Integrity(SRI)或签名校验











