高效处理大文件应使用 ReadableStream 边接收边解码边处理:从 fetch 获取 response.body 流,用 TextDecoderStream 解码避免中文截断,按 NDJSON 或 CSV 等格式渐进解析,并通过 AbortController 和 try/catch 主动控制异常与资源释放。

直接用 response.text() 或 file.text() 加载大文件,很容易让浏览器内存飙升、界面卡死。真正高效的做法是绕过全量读取,改用 ReadableStream 边接收、边解码、边处理——这才是 HTML5 处理大型数据流的底层正解。
从 fetch 获取原生流,别碰 text() 和 json()
fetch 返回的 response.body 就是现成的 ReadableStream,无需自己 new。但很多人一拿到就急着调 response.text(),这等于放弃流式优势,把整个响应体一次性塞进内存。
- 先校验:
response.ok为 true 且response.body不为 null - 立刻调用
response.body.getReader()拿到读取器(它只是“遥控器”,不自动开始读) - 真正干活的是
reader.read(),每次返回{ done, value: Uint8Array } - 推荐用
for await (const chunk of reader)循环,比手动 while + await 更稳,自动处理异常和结束
用 TextDecoderStream 解码,避开中文截断问题
response.body 是原始字节流,直接 toString() 只会输出一串数字。必须解码才能得到可读文本,但普通 TextDecoder 在跨 chunk 的 UTF-8 字符(比如一个汉字被切在两块之间)时会出错或丢字。
- 用
new TextDecoderStream('utf-8')创建解码流,它自带流式缓冲能力 - 或者用
new TextDecoder('utf-8', { stream: true })手动 decode,并传入{ stream: true }选项 - 不要拼接完整字符串再解析——把解码后的字符串 chunk 直接喂给后续处理器(如按行分割、JSON.parse 单行)
按格式渐进解析,不等整条流结束
标准 JSON.parse() 要求输入完整、闭合,没法处理流式中间态。得根据服务端返回的数据格式选策略:
- 如果是 NDJSON(每行一个 JSON 对象),解码后用
split('\n')切分,逐行JSON.parse(),失败就跳过该行 - 如果是连续 JSON(如
{"items":[{...},{...}),用partial-json-parser-js这类库,它能返回已确认的部分结构 - 如果是 CSV 或日志文本,可在解码后按换行符累积缓冲,凑够 N 行再批量处理并清空缓存
主动控制与兜底,避免流挂起或崩溃
流式过程容易受网络中断、用户取消、解码异常影响,必须提前设计退出路径:
- 创建
AbortController,fetch 时传{ signal },调abort()可同时终止请求和读取器 - 所有
reader.read()都包在try/catch里,捕获TypeError(如流被取消)或DOMException - 在
finally或catch中显式调reader.cancel(),释放底层资源 - 解析失败的片段记录位置偏移,继续尝试后续内容,不让单点错误阻塞整条流
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











