You need to enable JavaScript to run this app. 浏览器端JavaScript如何实现大JSON Blob/Stream/Buffer的只读向前解析?
优惠活动
大模型
产品
解决方案
定价
更多

浏览器端JavaScript如何实现大JSON Blob/Stream/Buffer的只读向前解析?

解决方案

问题根因

Oboe.js 内部默认会缓存所有已解析的JSON结构,同时你代码中把所有解析出的对象都存入blocks数组,两者叠加会快速消耗浏览器内存,当加载到25万条数据时达到浏览器内存上限,就会抛出内存溢出错误。

推荐实现方案

用专门针对浏览器流式场景设计的@streamparser/json库,它完全实现了向前只读的JSON解析能力,和.NET的Utf8JsonReader逻辑一致,不会缓存任何已处理的历史数据,最低内存占用可控制在MB级别。

实现代码

可通过npm安装依赖:npm install @streamparser/json,也可直接引入对应的CDN资源使用。

import { parser } from '@streamparser/json'

async loadAsync(file: Blob) {
    const blocks: any[] = this.blocks = []
    const ms = Date.now()
    let counter = 0

    // 直接读取Blob的字节流,不需要加载整个文件到内存
    const stream = file.stream()
        .pipeThrough(parser({
            // 匹配顶层数组的每一个元素,对应你的JSON结构:[obj1, obj2, ...]
            paths: ['$.*']
        }))

    // 逐元素遍历解析结果
    for await (const { value } of stream) {
        blocks.push(value)
        counter++
        
        if (counter % 5000 === 0) {
            this.logFn(`Loading: ${counter} items so far.`)
            // 可选:这里可以加await new Promise(r => setTimeout(r, 0))让出主线程,避免页面卡死
        }
    }

    this.logFn(`Finished loading ${counter} blocks in ${Date.now() - ms}ms`)
}

优化建议

  • 如果业务不需要保留所有已解析的对象,可以处理完单个value后直接丢弃,不存入blocks数组,内存占用会极低,哪怕几GB的JSON文件也能正常处理
  • 如果必须留存全量数据,建议每解析1~5万条就批量写入浏览器IndexedDB持久化,不要全量存在内存中

内容的提问来源于stack exchange,提问作者Luke Vo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 06:18:03