前端多线程大文件下载实践,提速10倍

html

然后来编写 html ,这没有什么好说的,写两个按钮来展示。

串行下载

多线程下载

js公共参数

const m = 1024 * 520;  // 分片的大小

const url = ‘http://localhost:8888/api/rangeFile?filename=360_0388.jpg’; // 要下载的地址

单线程部分

单线程下载代码,直接去请求以blob方式获取,然后用blobURL 的方式下载。

download1.onclick = () => {

console.time(“直接下载”);

function download(url) {

const req = new XMLHttpRequest();

req.open(“GET”, url, true);

req.responseType = “blob”;

req.onload = function (oEvent) {

const content = req.response;

const aTag = document.createElement(‘a’);

aTag.download = ‘360_0388.jpg’;

const blob = new Blob([content])

const blobUrl = URL.createObjectURL(blob);

aTag.href = blobUrl;

aTag.click();

URL.revokeObjectURL(blob);

console.timeEnd(“直接下载”);

};

req.send();

}

download(url);

}

多线程部分

首先发送一个 head 请求,来获取文件的大小,然后根据 length 以及设置的分片大小,来计算每个分片是滑动距离。通过Promise.all的回调中,用concatenate函数对分片 buffer 进行一个合并成一个 blob,然后用blobURL 的方式下载。

// script

function downloadRange(url, start, end, i) {

return new Promise((resolve, reject) => {

const req = new XMLHttpRequest();

req.open(“GET”, url, true);

req.setRequestHeader(‘range’, bytes=${start}-${end})

req.responseType = “blob”;

req.onload = function (oEvent) {

req.response.arrayBuffer().then(res => {

resolve({

i,

buffer: res

});

})

};

req.send();

})

}

// 合并buffer

function concatenate(resultConstructor, arrays) {

let totalLength = 0;

for (let arr of arrays) {

totalLength += arr.length;

}

let result = new resultConstructor(totalLength);

let offset = 0;

for (let arr of arrays) {

result.set(arr, offset);

offset += arr.length;

}

return result;

}

download2.onclick = () => {

axios({

url,

method: ‘head’,

}).then((res) => {

// 获取长度来进行分割块

console.time(“并发下载”);

const size = Number(res.headers[‘content-length’]);

const length = parseInt(size / m);

const arr = []

for (let i = 0; i < length; i++) {

let start = i * m;

let end = (i == length - 1) ?  size - 1  : (i + 1) * m - 1;

arr.push(downloadRange(url, start, end, i))

}

Promise.all(arr).then(res => {

const arrBufferList = res.sort(item => item.i - item.i).map(item => new Uint8Array(item.buffer));

const allBuffer = concatenate(Uint8Array, arrBufferList);

const blob = new Blob([allBuffer], {type: ‘image/jpeg’});

const blobUrl = URL.createObjectURL(blob);

const aTag = document.createElement(‘a’);

aTag.download = ‘360_0388.jpg’;

aTag.href = blobUrl;

aTag.click();

URL.revokeObjectURL(blob);

console.timeEnd(“并发下载”);

})

})

}

完整示例

https://github.com/hua1995116/node-demo

// 进入目录

cd file-download

// 启动

node server.js

// 打开

http://localhost:8888/example/download-multiple/index.html

由于谷歌浏览器在 HTTP/1.1 对于单个域名有所限制,单个域名最大的并发量是

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值