年初我还在写Java,一转头,已经写了一段时间的Python了 :)。 让程序员吵起来的话:“PHP是最好的语言”,我老板表示不服,说我进组晚,最好的语言是Perl,最好的IDE是Visual Studio。 我能说什么呢? 我可不打算和老板吵架。嗯, 最好的语言是Java。
也不知道老板会不会看我的文章,郑重声明:上面的表情包纯属搞笑效果,老板说什么我都是认真听的!从来没有装模作样!
好了好了,说正经的。
=====不正经分界线=====
最近工作中遇到的一个小问题(小问题我都得写一写,就是这么一个鸡毛的女人!),前端要加载的JSON数据重达6M左右,打开Chrome的控制台,就能看到在一个请求中,状态已经变成200了,但仍然要10s+ 去加载这么重的数据,于是,在给老板演示基于本地代码的效果的时候,就有几十秒的静默时间。嗯……慢到我想给老板表演胸口碎大石(没有)。
描述一下场景条件:
1. 前端显示数据为几百K
2. 前端实际加载了超过5M数据(有别用,不细说)
3. 服务器在国外,浏览器在国内
针对于上述问题,要采取JSON压缩的方式提高性能。网上给出两种策略: 1. 使用flask-compress 2.配置Nigix。 下面我们先来看一下flask-compress的使用。
写一个小小的模拟例子。 鉴于是在本地,网络传输很快,所以首先把Chrome 控制台Network的offline设置为Fast 3G,来模拟一个比较限制的网速,如下图:
然后下面是基本代码:
前端: 点击按钮请求后端数据,只显示‘content_to_show’
后端:读取一个大小为5M的文件内容,为‘content_not_show’,并和‘content_to_show’包成JSON返回(今天看了《毒液》,嘻嘻)
点击按钮,看一下Chrome的记录,28.34s加载了5M数据。
看一下Waterfall,可见Content Download花了27.78s,几乎可以说是网速限制了一切。日常生活中,这不是网的错,是我的,谁让我没有办理光纤入户呢?
然后呢,我们打开flask-compress的开关,发送爱心 ,biubiu~
这是README: https://github.com/jmcarp/flask-compress/blob/master/README.md
步骤超级简单: 1. 打开冰箱,2. 把大象塞进去,3. 关上冰箱门
哦,走错片场了。
重来。步骤很简单:
1. 安装flask-compress
2. import flask-compress
3. compress app
下面是使用flask-compress的代码,加两行,好很多~
然后我们再看一下效果,Size变成了5.4K,时间为毫秒级。很满意有没有!!
再看看Waterfall,可喜可贺~
下面让我们对比一下response的参数,左边是压缩的,右边的是不压缩的。
那多出来的参数怎么来的呢? 这就要看flask-compress做了什么了。
打开源文件,代码注释加空行总共119行,嗯,优秀的代码都这么短。
flask-compress做的事情就是,向app中插入自己的after_request方法,在这个after_request方法中进行数据压缩,参数设置:
if (app.config['COMPRESS_REGISTER'] and app.config['COMPRESS_MIMETYPES']):
app.after_request(self.after_request)
after_response中主要的代码,根据各种参数判断要不要做压缩,压缩完了设置encoding等参数,告诉浏览器如何压缩的,使浏览器知道如何解压。
回答上面图片:没有。
这里提出一个问题: 根据flask-compress 的代码,它是作用在application级别的,也就是说,经过这个application的请求都执行这个after_response方法,compress是需要消耗CPU的,如果不想所有的response都压缩怎么处理?
我认为有两种解决办法:
1. 设置flask-compress提供的各种参数,来达到控制的效果
2. 这个是我想的,抽取压缩方法,结合flask的make_response方法,压缩特定的请求。
分开来说,第一点,这种产品肯定会考虑到我们的问题,如果每个请求都压缩,就有点笨了。可以设置两个参数控制是否压缩:COMPRESS_MIN_SIZE 和 COMPRESS_MIMETYPES。
COMPRESS_MIN_SIZE 控制最小压缩阈值,小于这个值的就不压缩,默认值是500. COMPRESS_MIMETYPES 控制的是压缩类型,不在类型范围内不压缩,默认值是['text/html','text/css','text/xml','application/json','application/javascript']。设置方式如下,测试代码我就不写啦,大家自己玩玩~
另外,还有第三个参数,COMPRESS_LEVEL,这个参数是控制压缩级别,就是gzip的压缩级别,1-9,1的压缩速度最快,压缩率最小,9 反之,默认值是6。在上面的例子中看不出来效果,我在项目中做测试的时候,有一种压缩使用了很多时间经历,特别设置了这个参数,效果立刻不一样~
第二种,通过make_response方法获得response,复制flask-compress的代码内容,进行压缩。 经过测试,一样可以达到效果,作用域就变成了当前方法了。
除了flask-compress,常用的压缩方法还有配置nigix。 这篇就不说啦,如果我能活过接下来的UAT,那我再继续写(基于前面的天津游记过了半年仍然没有后续,这个nigix的文章,嗯……have a nice life……)
==============================
写之前觉得很有意思,终于写完了,反而觉得像是在做测评,写完了就不好玩了。果然写东西就是要享受过程。 比如,一开始没有注意到Chrome控制网速的开关,本地load数据,500M也就用了几秒好嘛~看了之后差点崩溃,我去哪里找个远端服务器嘛~难道去找哆啦A梦・陈宝石? 说来还是我脑子好使~🤪办法总比困难多~自己制造的困难自己放弃嘛(不是) ~
这篇废话连篇的文章,就当作是又一个光棍节给自己的小小献礼。
P.S. 最好的浏览器是IE,我说这个应该没人反对吧?