核心目标是避免主线程卡顿,通过Web Worker分块加载、流式解析JSON,事件驱动过滤、零拷贝传输、动态更新与取消机制及缓存提升性能与可控性。

把大型 JSON 的解析挪到 Web Worker 里,核心目标不是让解析“更快”,而是不让它拖垮页面——主线程继续响应点击、滚动、动画,用户感觉不到卡顿。
分块加载 + 流式解析,别等整个文件
别用 fetch(...).then(r => r.json()) 一次性拉下几 MB 甚至上百 MB 的 JSON 字符串再传给 Worker。那样内存峰值翻倍,还失去控制权。改用 response.body.getReader() 边收边处理:
- 如果是 JSONL(每行一个 JSON 对象),按换行符切块,每块送进 Worker 即刻解析
- 如果是标准 JSON,用状态机跟踪 { 和 } 的嵌套层级,拼出完整对象后再交给解析器
- Worker 内推荐使用 stream-json 或 jsonparse 这类事件驱动解析器,收到 startObject 就准备缓存,endObject 就尝试过滤并回传
过滤逻辑必须在 Worker 里执行
把原始数据全发过去,再让主线程筛?等于白忙一场。真正起效的关键是:所有判断都发生在 Worker 线程。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 用户输入关键词或切换状态时,用 postMessage({ type: 'updateFilter', keyword: 'xxx' }) 动态更新 Worker 内部变量
- Worker 每解析出一个对象,立刻执行 if (obj.status === 'active' && obj.name.includes(keyword)),只把匹配项结构化发回
- 避免在消息中传递未过滤的原始数组——哪怕只是临时变量,也会拉高内存和序列化开销
用 transferable 零拷贝传数据
Worker 和主线程之间传大数据,JSON.stringify → postMessage → JSON.parse 是典型性能黑洞。要绕过这个坑:
- 主线程读取文件后,用 TextEncoder.encode() 转成 ArrayBuffer,再调用 postMessage(buffer, [buffer]) 实现零拷贝
- 如果必须传对象,优先用 structuredClone() 替代手写序列化,它支持 Map、Date、RegExp 等原生类型,更安全也更快
- 绝对不要往 message 里塞 DOM 元素、函数、循环引用对象——会静默失败或直接报错
加取消机制和缓存,提升可控性
用户点“取消”或切换筛选条件时,正在跑的解析不能放任不管;首次成功结果也不该每次重来。
- 主线程创建 AbortController,发送 { type: 'abort' } 消息,Worker 内监听 signal.aborted 主动退出循环
- 解析完成的结果(比如过滤后的数组或 ArrayBuffer)存进 IndexedDB,下次加载先查缓存,命中就跳过解析步骤
- Worker 内解析完成后及时清空局部变量,尤其避免闭包长期持有大对象引用

















