來自廣州藍景分享帖:關于性能優(yōu)化的篇
有一天,產(chǎn)品經(jīng)理跟我們我們提了一個關于人臉識別活動的小程序,基本上可以理解為就是上傳圖片,然后識別出這個人的魅力、年齡等相關特性,這么一個小活動。開發(fā)的過程是那么的愉悅且輕松,但當我們上線后,才發(fā)現(xiàn)原來這只是暴風雨前的寧靜。因為我們在大范圍內(nèi)測中,有部分用戶反映識別較慢,有時候甚至需要等待超過5秒。所以,這是一篇關于程序猿智斗性能瓶頸的故事!
02
猜測問題
那智斗之前,肯定是需要先找找突破點和最有可能出問題的地方,所以,我們先從分析整個項目的流程開始,用一張圖即可說明關系

梳理項目流程可以發(fā)現(xiàn),最有可能出現(xiàn)問題的地方,有兩點。第一點是圖片上傳整個環(huán)節(jié),第二點是圖片識別這個環(huán)節(jié)。所以,我們針對這個流程做了一次大數(shù)據(jù)量并取平均值的統(tǒng)計。
03
測試工具
所以,我們就開始用壓測工具去模擬高并發(fā)的場景,來收集測試的性能數(shù)據(jù)。
這次,我們使用Jmeter進行壓測,因為Jmeter可提供更強大的服務,Jmeter的入門使用可參考我們的手冊
http://mybook.bluej.cn/tools/docs/#/lesson/jmeter
這是我們在Jmeter下對測試接口的配置
//

//

//
//
由于我們的后臺是php,所以后臺在關鍵代碼使用time()函數(shù)獲取當前時間戳,代碼結束時也記錄時間戳,通過計算進行時間差,來粗略計算圖片每個環(huán)節(jié)的用時。
獲取圖片耗時400.743豪秒
識別圖片耗時 2623.370毫秒
返回結果處理耗時1.090毫秒
總耗時 3025.203毫秒
結果再次證明,我們優(yōu)化的重點應該就是圖片上傳,和圖片識別這兩個環(huán)節(jié)。這時,我們重點應該是控制圖片的大小,因為經(jīng)驗告訴我們,這塊是嚴重影響著文件的上傳速度和識別接口的壓力。所以,我們分析了一下源碼。發(fā)現(xiàn)在小程序端,并沒有針對用戶拍攝或選擇的圖片進行必要的處理,導致不同的機型,所產(chǎn)生的圖片大小會有明顯的差異,那如何去抹平這種差異,把所有的機型表現(xiàn)都統(tǒng)一在同一起跑線上,所以,我們借助了canvas
04
解決問題
一、前端通過canvas將用戶上傳的圖片大小控制50KB以下
用到的canvas微信小程序api(摘自微信小程序官方文檔)
wx.createCanvasContext //創(chuàng)建 canvas 的繪圖上下文 CanvasContext 對象
CanvasContext.clip //從原始畫布中剪切任意形狀和尺寸
CanvasContext.drawImage //繪制圖像到畫布
CanvasContext.restore //恢復之前保存的繪圖上下文
CanvasContext.draw//將之前在繪圖上下文中的描述(路徑、變形、樣式)畫到 canvas 中
操作思路:
1:獲取圖片信息
2:創(chuàng)建canvas上下文
3:圖片尺寸邊界判斷
4:裁切canvas
5:將圖片畫到canvas中

二、前端做好緩存,減少請求次數(shù),減輕服務器的壓力
例如:
(1)緩存token,設置合適的過期時間
(2)近期授權過,可提前登錄
(3)頁面圖片傳遞,使用緩存
后記補充:
通過這次圖片的控制,我們發(fā)現(xiàn)影響傳輸效率的,歸根到底,還是圖片的大小,與尺寸無關,但圖像識別效率卻跟圖像大小,圖像像素點復雜度有關。所以一個接口的影響因素很由很多方面構成的,如果想繼續(xù)深入,我們可以往圖像識別原理進行深挖。
在相同配置的服務器下:
尺寸640x608大小37KB 請求耗時:1096ms
尺寸726x960大小40KB 請求耗時:973ms
尺寸290x230大小20KB請求耗時:1080ms
關于這個項目,我還特意去錄制了一個視頻,歡迎關注“廣州藍景公司”公眾號觀看完整視頻。
目前我們還有一個線下前端技術交流哦,以小組圍圈式學習交流,每組限8人。