前端较大数据传输优化方案(下)

122 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

前言

上一节我们针对前端较大数据传输所造成的页面响应缓慢的问题,使用了分片的思路进行优化处理,但是由于分片会对字节码进行截取,导致了在文本解析的过程中在截取位置出现了乱码的问题,本节将针对这一问题,做进一步的优化,不废话马上开始

参考代码

为了保障字符能够正常解析,我们需要找到一个特殊的值来对字节数组进行截取,说实话这个特殊值是我看了相关的代码反推出来的,先看下完整的代码

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)

2022-12-05 21 45 28

好了,本篇针对txt文本文件分片加载的优化到此告一段路,感觉对网络数据的传输又有了新的认识,由于写该主题时明显感觉有些吃力,也意识到了自己的很多不足,后面再接再厉,争取把相关知识点搞懂搞透