前言
上一节我们针对前端较大数据传输所造成的页面响应缓慢的问题,使用了分片的思路进行优化处理,但是由于分片会对字节码进行截取,导致了在文本解析的过程中在截取位置出现了乱码的问题,本节将针对这一问题,做进一步的优化,不废话马上开始
参考代码
为了保障字符能够正常解析,我们需要找到一个特殊的值来对字节数组进行截取,说实话这个特殊值是我看了相关的代码反推出来的,先看下完整的代码
async function loadText (url) { const res = await fetch(url) // 传输了多少读多少 const reader = await res.body.getReader() const decoder = new TextDecoder() // 文本解码器 let flag = false let remainChunk = new Uint8Array(0) while(!flag) { const { value, done } = await reader.read() // console.log(done); // 加载状态 // console.log(value); // 字节数组 flag = done if (flag) return const lastIndex = value.lastIndexOf(10) // 数值10位置进行切分 const chunk = value.slice(0, lastIndex + 1) const readChunk = new Uint8Array(remainChunk.length + chunk.length) readChunk.set(remainChunk); readChunk.set(chunk, remainChunk.length) remainChunk = value.slice(lastIndex + 1) const text = decoder.decode(readChunk) console.log('======'); console.log(text) } } 复制代码
这段代码琢磨了许久,通过使用了一些特殊的字节数组解析出来猜测,10这个位置要么应该是一个换行符(若有相关资料,望大佬留言指教)
const decoder = new TextDecoder() // 文本解码器 console.log(decoder.decode(new Uint8Array([155,135,227,128,130,10]))) 复制代码
思路
计算解析数组的长度
找到 10 这个分割点后,后面的事情就简单多了,我们只需要每次读取到片段时,只解析上一次的末尾开始到这一次10处即可
const { value, done } = await reader.read() const lastIndex = value.lastIndexOf(10) // 记录本次最后一个 10 的位置 const chunk = value.slice(0, lastIndex + 1) // 截取本次数组 // 以上一次未解析的内容长度 + 本次需要解析的长 = 需要初始化的字节数组长度 const readChunk = new Uint8Array(remainChunk.length + chunk.length) 复制代码
加载数组内容
readChunk.set(remainChunk) // 从 0 开始,加载上一次未解析内容 readChunk.set(chunk, remainChunk.length) // 从上一次未解析内容末尾开始,加载本次内容 复制代码
暂存本次未解析内容
remainChunk = value.slice(lastIndex + 1) 复制代码
解析本次内容并展示
const text = decoder.decode(readChunk) console.log('======'); console.log(text) 复制代码
好了,本篇针对txt
文本文件分片加载的优化到此告一段路,感觉对网络数据的传输又有了新的认识,由于写该主题时明显感觉有些吃力,也意识到了自己的很多不足,后面再接再厉,争取把相关知识点搞懂搞透