来自广州蓝景分享帖:关于性能优化的篇
有一天,产品经理跟我们我们提了一个关于人脸识别活动的小程序,基本上可以理解为就是上传图片,然后识别出这个人的魅力、年龄等相关特性,这么一个小活动。开发的过程是那么的愉悦且轻松,但当我们上线后,才发现原来这只是暴风雨前的宁静。因为我们在大范围内测中,有部分用户反映识别较慢,有时候甚至需要等待超过5秒。所以,这是一篇关于程序猿智斗性能瓶颈的故事!
02
猜测问题
那智斗之前,肯定是需要先找找突破点和最有可能出问题的地方,所以,我们先从分析整个项目的流程开始,用一张图即可说明关系

梳理项目流程可以发现,最有可能出现问题的地方,有两点。第一点是图片上传整个环节,第二点是图片识别这个环节。所以,我们针对这个流程做了一次大数据量并取平均值的统计。
03
测试工具
所以,我们就开始用压测工具去模拟高并发的场景,来收集测试的性能数据。
这次,我们使用Jmeter进行压测,因为Jmeter可提供更强大的服务,Jmeter的入门使用可参考我们的手册
http://mybook.bluej.cn/tools/docs/#/lesson/jmeter
这是我们在Jmeter下对测试接口的配置
//

//

//
//
由于我们的后台是php,所以后台在关键代码使用time()函数获取当前时间戳,代码结束时也记录时间戳,通过计算进行时间差,来粗略计算图片每个环节的用时。
获取图片耗时400.743豪秒
识别图片耗时 2623.370毫秒
返回结果处理耗时1.090毫秒
总耗时 3025.203毫秒
结果再次证明,我们优化的重点应该就是图片上传,和图片识别这两个环节。这时,我们重点应该是控制图片的大小,因为经验告诉我们,这块是严重影响着文件的上传速度和识别接口的压力。所以,我们分析了一下源码。发现在小程序端,并没有针对用户拍摄或选择的图片进行必要的处理,导致不同的机型,所产生的图片大小会有明显的差异,那如何去抹平这种差异,把所有的机型表现都统一在同一起跑线上,所以,我们借助了canvas
04
解决问题
一、前端通过canvas将用户上传的图片大小控制50KB以下
用到的canvas微信小程序api(摘自微信小程序官方文档)
wx.createCanvasContext //创建 canvas 的绘图上下文 CanvasContext 对象
CanvasContext.clip //从原始画布中剪切任意形状和尺寸
CanvasContext.drawImage //绘制图像到画布
CanvasContext.restore //恢复之前保存的绘图上下文
CanvasContext.draw//将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
操作思路:
1:获取图片信息
2:创建canvas上下文
3:图片尺寸边界判断
4:裁切canvas
5:将图片画到canvas中

二、前端做好缓存,减少请求次数,减轻服务器的压力
例如:
(1)缓存token,设置合适的过期时间
(2)近期授权过,可提前登录
(3)页面图片传递,使用缓存
后记补充:
通过这次图片的控制,我们发现影响传输效率的,归根到底,还是图片的大小,与尺寸无关,但图像识别效率却跟图像大小,图像像素点复杂度有关。所以一个接口的影响因素很由很多方面构成的,如果想继续深入,我们可以往图像识别原理进行深挖。
在相同配置的服务器下:
尺寸640x608大小37KB 请求耗时:1096ms
尺寸726x960大小40KB 请求耗时:973ms
尺寸290x230大小20KB请求耗时:1080ms
关于这个项目,我还特意去录制了一个视频,欢迎关注“广州蓝景公司”公众号观看完整视频。
目前我们还有一个线下前端技术交流哦,以小组围圈式学习交流,每组限8人。