小程序代碼在ios上很溜,但是安卓機(jī)上性能問題很多,低端安卓機(jī)對(duì)性能調(diào)優(yōu)更是要求賊高,稍不注意,頁面就能卡死。

性能問題基本都是cpu不夠用導(dǎo)致的卡頓,這種卡頓可能是1)dom太大,內(nèi)存爆滿 2)js操作頻繁,js進(jìn)程繁忙 3)渲染問題,可能是被js阻塞了,也有可能是所在環(huán)境的渲染機(jī)制不夠優(yōu)化

在本次為小程序開發(fā)的雙十一會(huì)場(chǎng)頁面時(shí),總結(jié)出以下經(jīng)驗(yàn)

存在的性能問題及解決方案

在開發(fā)中發(fā)現(xiàn)在低端機(jī)上幾個(gè)小程序端需要注意的事:

  1. dom大了后,bindtap事件會(huì)不靈敏,短時(shí)間連續(xù)觸發(fā)的bindtap事件后續(xù)的會(huì)丟失。原生小程序測(cè)試時(shí),3000個(gè)dom節(jié)點(diǎn)就有丟失現(xiàn)象。后來嘗試了使用touchstart和touchend去模擬,發(fā)現(xiàn)雖然touchstart很靈敏,但是touchend會(huì)丟失(個(gè)人猜測(cè)小程序的tap事件也是通過touchstart和touchend模擬的)。我們的大促會(huì)場(chǎng)600個(gè)商品時(shí)我算了下大約13000個(gè)dom節(jié)點(diǎn),低端安卓機(jī)事件丟的很嚴(yán)重,間隔幾乎是秒級(jí)別才能觸發(fā)下一次事件。所以解決方案只能減小dom量,添加dom懶加載和動(dòng)態(tài)移除的邏輯,經(jīng)過多次測(cè)試,比較理想的效果是預(yù)加載2屏

2)滾動(dòng)時(shí)setState卡頓嚴(yán)重,如果滾動(dòng)時(shí)有觸發(fā)setState操作,那么setState成功可能發(fā)生在幾秒后,即使?jié)L動(dòng)操作在幾百ms內(nèi)就結(jié)束了。這就導(dǎo)致導(dǎo)航類功能的滾動(dòng)跟隨效果在安卓機(jī)上反應(yīng)特別慢,滾停到某個(gè)商品樓層后,過了1-2s才導(dǎo)航條才突然動(dòng)一下,所以最終取消了安卓的滾動(dòng)跟隨效果。(不根據(jù)版本取消效果,是因?yàn)榘l(fā)現(xiàn)即使是安卓較新的7.1版本在性能不好的機(jī)器上也會(huì)這樣)

3)白屏問題

快速瘋狂滾動(dòng)頁面,前面的頁面沒渲染出就不停的往后滾,發(fā)現(xiàn)小程序不是優(yōu)先渲染可視區(qū)域,而是一定要把曾經(jīng)滾過的區(qū)域按順序渲染了。所以如果快速瘋狂滾動(dòng),后面的內(nèi)容白屏等待時(shí)間會(huì)很久??紤]到正常用戶不會(huì)有這種需求,想看后面的內(nèi)容可以通過樓層導(dǎo)航過去,而且這個(gè)問題我們也找不到解決方案,所以這個(gè)現(xiàn)象沒有處理。

注意事項(xiàng)

1)懶加載+動(dòng)態(tài)移除非可視范圍內(nèi)的內(nèi)容,讓dom小下去

2)耗時(shí)的js操作異步化,不要阻塞主線程。落地一點(diǎn)說,小程序里不要做頻繁的setState操作,不在state里放跟視圖層無關(guān)的內(nèi)容。譬如我之前為了代碼清晰,把導(dǎo)航功能模塊里的樓層位置信息放到了視圖層也用的一個(gè)變量里,其實(shí)視圖層并不直接用到這個(gè)信息,這個(gè)信息為了準(zhǔn)確,又會(huì)在每次滾動(dòng)后重新計(jì)算,導(dǎo)致頻繁setState,且set的是跟視圖層無關(guān)的數(shù)據(jù),優(yōu)化后,性能提升很明顯。

3)還有跟小程序本身相關(guān)的,wx.createSelectorQuery系列接口都是異步的,會(huì)受主進(jìn)程影響,如果主進(jìn)程繁忙,這個(gè)接口返回時(shí)間會(huì)延遲很久也是s級(jí)別的,對(duì)于樓層導(dǎo)航和懶加載這種需要頁面各模塊位置信息的功能,不能每次操作都等這個(gè)接口返回,可以緩存數(shù)據(jù),取緩存,然后用戶的操作觸發(fā)調(diào)接口更新緩存,在緩存有更新時(shí),為了更準(zhǔn)確,也可以主動(dòng)觸發(fā)下需要位置信息的后續(xù)處理函數(shù)。

4)少用scroll-view,這個(gè)組件對(duì)性能影響實(shí)在太大,單純的只是需要一塊可滾動(dòng)區(qū)域,請(qǐng)用css+view解決

5)不知道微信的小程序做了什么,滾動(dòng)操作時(shí)進(jìn)程異常繁忙,滾動(dòng)停止后很久才是可操作和執(zhí)行js狀態(tài),所以盡量少的觸發(fā)在滾動(dòng)時(shí)的回調(diào)函數(shù),節(jié)流函數(shù)必須合理用起來。

性能調(diào)優(yōu)是個(gè)漫長(zhǎng)的取舍過程,需要不斷測(cè)試來獲取最優(yōu)效果。cpu只有那么多,一段時(shí)間只能干那么多事,那就要干效果較好最重要的事。