你觉得你的web应用只可以响应得更快一点吗——让上传速度加快10倍!

“高层次的抽象” 作者: Tomasz Urbaszek

我们会对在发现应用响应慢的时候做一些优化,但是现实效果都不怎么满意。正如它所显示的,最慢的部分是在我们应用中上传文件的时候。然而是否还有加快上传文件速度的可能呢?

在我们着手优化之前先来一个简短的介绍。如果你是正在处于一个商业应用的开发当中,你有可能会遇到关于应用不能及时响应的需求。问题的瓶颈可能是由以下的其中一点造成的:

  • 极少的优化代码
  • 服务器或客户设备运行慢
  • 不好的网络条件

第一条,无论是遗留下来的代码,没有优化的数据库查询语句或者在浏览器的JavaScript代码块,都可以相对轻松地跟踪和修复。(轻松的意思是指“我知道这该怎么做”,而不必是“这是小菜一蹀”)。

假设你的代码已经很高质量了,但是你的服务器还是无法很好地对所有用户提供服务的时候——这实际上听起来像是一个对你和你的业务相当好的一个信号。你可能会通过更换更强大的服务器来处理所有正在增长的请求。还是说它可能只是一个高度隐藏的潜在问题?那么网络分发内容(CDN)这篇文章可以是你需要的。

web应用一般不会因为用户设备而运行慢,因为几乎所有设备都可以运行能够提供相当好体验的浏览器。

所有关于因特网的文章似乎都有一张照着路由器和网缆的图片 ¯(ツ)

我们现在只剩下个可能的原因了:差的网络条件。虽然现在的网络下载的速度越来越快,但是你还是主动地通过资源最小化和压缩等方法来要让你的网店加载得更快。所有的现代网站服务器都支持gzipped文件压缩技术,这是一种能让客户端下载最少数据来显示你 的网站的技术。(如果你还没有使用gzip来压缩,这也许是个好机会来考虑一下这样做)。但是如果你想通过其它方式来加快响应,那又该怎么做呢?

欢迎来到上传的未知领域

上传文件这个过程有什么东西是还非常不了解的呢?对于初学者来说,如果我们对比一下上传和下载的速度,会发现很多人用的是不对称的因特网(尽管你不是网络的源头,但你也是这网络中的其中一员不是吗?)。因此不对称网络就意味着上传速度会比下载速度慢10倍以上。所以当用着60Mbps的网络时感觉速度还不错,但6Mbps的上传听起来就相当的慢了。这实际上还不到1MB/s。

这感觉就像8Mbps的网络来上传一个160MB大小的文件那样令人沮丧不是吗? ლ(ಠ_ಠლ)

此外,不像服务器,浏览器没有自带在上传之前压缩数据的能力。所以有了在慢网络下上传大文件会卡死的情况发生了。

我们提出一个解决这个问题的简单主意。在我们不用强迫人们更换更快网络的情况下,我们可以参考在服务器那样的解决方案,尝试发送更少的数据。但是怎么才能在浏览器上传之前压缩一下数据呢?

初见Pako

什么是pako?根据介绍,它是一个_zlib的javascript接口,非常的快!换句话说,我们使用pako就能给浏览器加上了强大的gizp数据压缩功能,刚好符合我们之前讨论的解决方案,而且还省力省心。举个例子,在我们上传文件之前,你可以通过这行命令来压缩数据:

`**var** compressed_file = pako.deflate(input_file);`

这不是很简单吗?不过先让我们停下来讨论一下什么时候你才真正地需要压缩数据。

我们不能把所有的东西都拿去压缩

首先,你是可以把所有的数据都拿去压缩的,但是这并不很符合常规。比如,你不需要使用gzip对图片或者视频进行压缩(至少大多数它们标准的格式像jpg或者mpeg已经经过很大程度的压缩了)。

在另一方面,对于文本数据,已经压缩得很好了。而对于文件,我们一直期待能够达到90%的压缩比率,而且纯文本还要被打包得很好。在我们案例中就是关于3D的文件(obj, stl 等等)。对于你来说也许是一些Excel的文件或者Photoshop的大文件等着上传。不管,反正要先试图把它们压缩,之后你就会对压缩后省下的空间而感到惊讶。

第一行是没有被压缩过的文件,第二行是经过压缩后的同一份文件

但是压缩的过程是很慢的

然后接下来就是上传文件了。还记得我们是怎么讨论异步网络的?在上传速度很慢的情况下,关键的地方就是应该考虑怎么让压缩时间比上传的时间少。想要实现这一点其实并不困难,只要你的文件已经经过了很好的压缩。上传压缩过的小文件会比上传未压缩的大文件快。

为了确保我们在压缩的时候不会花太多的时间,我们会用最低的压缩档次(9分之1),这是一个最快地显著减少文件大小的模式。在大多数情况下你不会使用更高的压缩档次。

就像你所看到的那样,为了提高2-3%的压缩比率,我们需要花费更多更多的压缩时间。(在这个点上我应该向你展示一个关于时间和文件大小的对比图表,但是后来我觉得也许让你自己去实践获得的对比效果会更好)

你只需要传一个level选项就可以改变pako的压缩档次,就像下面语句:

`**var** compressed_file = pako.deflate(input_file, {level: 1});`

现在既然我们知道了一系列的可以加快上传的解决方法,就让我们来检查一下应用它们的实际效果。

我们真的使上传变得更快了吗?

事实上是的。

左边的是上传未经压缩的文件,而右边的则是经过压缩过的。我们很容易在它们俩中作出选择。

在经过针对这个方法一段时间的测试后,我们决定把它使用到我们的app项目中。在我们项目中,我们要上传一些JSON格式的3D模型数据。在压缩之前,他们有时会达到5-6MB。而这些文件的压缩比率可以达到90%,也就是说我们只要上传0.6M的数据来代替6MB。现在,在6Mbps的上传速度环境下,客户只要等待0.8s而不是8s就可以上传完毕。期间压缩这些文件也只是花了少于0.1s的时间,所以我们决定采用这种方案。

但是你不必一定相信我。在最后我从网上随机地抽取一些人。

为什么你不去实践一下

我准备了一个很小的demo应用 来让你决定是否能在你的项目中使用。在选择上传速度和选择需要上传的文件后,这个demo应用会自动地压缩它和模拟上传过程。你不用担心它是否真的上传你所选择的文件并随便发布到其它地方,它只是单纯地改变进度条,以便你可以对上传这些未压缩和压缩过的文件所需的时间进行对比。

在你的应用是尝试上传一些文本文件、二进制数据或者其它你想上传的东西。

接下来是什么?

还有一些事我们需要记得。最重要的就是现在你的服务接收的是经过压缩的数据,因此你必需要去解压后才能使用它。解压是永远比压缩快的,所以不必担心我们会在解压上花费很多额外的时间。

另外一个需要留意的是压缩不是瞬间就完成的。对于一个很大的文件可能会需要一些时间来上传(比如一些大小为450MB的文件,你可能需要等等大约30秒的时间来上传)。为了良好的用户体验,应该尽量地让你的网站不处于阻塞状态,可能用分块来上传文件(pako已经支持这个功能),或者尝试一些Web Workers。

好了,就是这么的简单,不知道在你看完这个解决方案后对你的应用会有什么帮助呢?


往期精选文章

使用虚拟dom和JavaScript构建完全响应式的UI框架

扩展 Vue 组件

使用Three.js制作酷炫无比的无穷隧道特效

一个治愈JavaScript疲劳的学习计划

全栈工程师技能大全

WEB前端性能优化常见方法

一小时内搭建一个全栈Web应用框架

干货:CSS 专业技巧

四步实现React页面过渡动画效果

让你分分钟理解 JavaScript 闭包



小手一抖,资料全有。长按二维码关注京程一灯,阅读更多技术文章和业界动态。

本文分享自微信公众号 - 京程一灯(jingchengyideng)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏hotqin888的专栏

用beego vue.js element axios 写flow办公流程——系列五

自己的认识:一定要用独立的前端,即vue.js前端项目必须是独立的,独立的服务,不要放beego里的view里作为tpl页面。虽然,放beego view里的t...

16300
来自专栏进击的全栈

认识Set和Map数据结构

tips : 由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致,而entries方法返回的...

17570
来自专栏KEN DO EVERTHING

快速入门Vue

刚进公司做的第一个项目,刚好前端人手不足,需要我们后端同时兼顾前后端的工作,采用的iview UI框架,基于vue.js。

16810
来自专栏前端vue

vue-cli3项目创建-配置-发布

(2) 修改user module -- src/store/module/user.js

4.3K40
来自专栏编程软文

分布式阿波罗Apollo配置中心

为什么要使用apollo,在我们开发分布式微服务项目的时候,那些配置一旦变更,就需要重启服务,这样非常不友好。因此我们考虑动态更改配置文件当中的配置,所以把那些...

29520
来自专栏码匠的流水账

聊聊flink的Execution Plan Visualization

本文主要研究一下flink的Execution Plan Visualization

14620
来自专栏编程微刊

js通过input框输入属性和值,改变div的属性

js实现在input框里面输入属性和值,页面的 div的属性根据输入的属性和值进行变化。

67450
来自专栏成猿之路

2019开发者调查趋势与方向报告出炉

近日国外开发者平台 HankerRank 发布了 2019 年开发者技能调查报告,该报告根据对71,281位开发者的调查得出。作者从中选取了一部分,给大家解读一...

14540
来自专栏娱乐心理测试

mpvue网络接口请求封装

在mpvue中我们同样使用小程序的原生API wx.request进行请求,具体方法如下:

48430
来自专栏python教程

基于django的视频点播网站开发-step9-后台视频管理功能

从本讲开始,我们开始视频管理功能的开发,视频管理包括视频上传、视频列表、视频编辑、视频删除。另外还有视频分类的功能,会一同讲解。这一讲非常重要,因为你将学习到一...

24130

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励