FileReader读取大文件
·
2 min read
前端采用FileReader可以读取文件内容,但是在读取大文件,比如1-3GB文件时发现会有显著卡顿。这里Mark下优化办法。
卡顿原因
全量读取文件的话,文件内容会都存入浏览器内存中,因此会出现卡顿。
解决办法
文件file进行slice分片,每次异步读取分片数据。
const chunkSize = 1 * 1024 * 1024; // 1MB
function readChunk(file, start, chunkSize) {
const reader = new FileReader();
return new Promise(resolve => {
reader.onload = (evt) => {
// console.log(evt.target.result);
resolve(evt.target.result);
};
reader.readAsArrayBuffer(file.slice(start, Math.min(start + chunkSize, file.size)));
})
}
对比
以2.3GB数据为例
使用FileReader.readAsArrayBuffer分1MB片读取数据,时间开销如下
使用FileReader.readAsArrayBuffer全量读取文件,发现一直没有读取结束
以1.98GB数据为例
- 分片读取
- 全量读取
结论
- 由上可以看到,分片读取文件内容是节约性能的,且更快能够读取到指定部分内容,但读取总时间并不一定比全量少。但文件越大,差距会越大。
- 2GB以上文件浏览器一次性全量读取会有问题。
延伸
在前端处理文件二进制是经常会遇到Blob和ArrayBuffer,如果只是单纯分片数据推荐Blob,blob只是原数据视图本身并没有打开销,因此比如上传文件,可以直接file.slice进行分片发送服务端即可。但如果需要前端读取文件内功,或者还要修改文件,则推荐ArrayBuffer。