因为大文件上传耗时比较长,所以呢就有了分片上传的想法。于是就开启艰难的上传之旅。

问题1:Queued at时间长在8s以上

​ 调试上传29M的图片,切片大小每个1M并发请求29个,上传时长得1分钟左右。分析发现Network中Queued at时间长,查了一下相关资料发现如果是HTTP/1.0和HTTP/1.1有六个TCP连接的限制,于是就调整并发为最高6个。调整之后,时间明显缩短。

问题2:Request send时间长在7s以上

​ 因为前后端的问题一个内网一个外网,所以提供了两个切片上传的接口。后端的接口29M文件上传只需要30s,前端的得1分钟。很奇怪,分析发现Network中request send时间在7s以上。找了好长时间没有发现问题,对比代码也是一样的。对比head头,发现后端接口的请求头里Accept-Encoding: gzip, deflate, br,响应头Content--Encoding: br;而前端请求头里Accept-Encoding: gzip, deflate,响应头Content--Encoding: gzip。

扩展:Brotli 压缩算法 :Google 在 2015 年 9 月推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率。

Brotli 压缩算法具有多个特点,最典型的是以下 3 个:

  • 针对常见的 Web 资源内容,Brotli 的性能相比 Gzip 提高了 17-25%;
  • 当 Brotli 压缩级别为 1 时,压缩率比 Gzip 压缩等级为 9(最高)时还要高;
  • 在处理不同 HTML 文档时,Brotli 依然能够提供非常高的压缩率。

到此我们就知道request send时间长的问题所在了。

问题3:Refused to set unsafe header "Accept-Encoding"

​ 因为问题2对比head头发现Accept-Encoding缺少br,于是前端就加了一个Accept-Encoding: gzip, deflate, br的head头,导致了现在的问题。谷歌搜索发现这个Accept-Encoding是禁止修改的标头,所以很显然这一步是错的。由于不了解b r,所以搜索了好久发现br 压缩只有在 https 下生效。接下来问题就引刃而解了,因为我们后端测试环境是https的,所以压缩算法有br,前端是http的所以没有br算法。果然把前端域名调整成https之后上传速度一下就上来了。

搞到了最后了解到了一种最好的解决方案就是直传到阿里云的oss,详见https://help.aliyun.com/document_detail/31924.html

参考:
https://developer.chrome.com/docs/devtools/network/reference/
https://developer.mozilla.org/zh-CN/docs/Glossary/Forbidden_header_name
https://en.wikipedia.org/wiki/Brotli