背景
體驗評分 Audits 是微信開發者工具內置的一項功能,會在小程序運行過程中實時檢查,分析出一些可能導致體驗不好的地方,並且定位出哪里有問題,以及給出一些優化建議。
京喜小程序作為京東戰略級業務,擁有千萬級別的流量入口,經過長時間的業務迭代,代碼邏輯已經十分復雜臃腫,有迫切的性能優化需求。因此,結合體驗評分功能,以京喜首頁做試點,我們進行了一次體驗評分的優化實踐。目的是探索小程序體驗評分的指標原則:拿到100分的小程序應該是什么樣子的;同時希望借此給項目優化提供更多思路。
我會按照「了解首頁評分現狀,分析扣分項規則,解決扣分項」這個思路來介紹,就讓我們開始吧~
京喜首頁評分現狀
打開小程序開發者工具-調試器-Audits,點擊運行,操作頁面滾一滾點一點,然后點擊結束。
評分結果會根據評測頁面內容差異、操作習慣、有無緩存有一定浮動,下圖是京喜首頁的一次評分:總分68,性能、體驗、最佳實踐都有扣分,合計8項扣分項,后面我們來逐條分析這些扣分項。

扣分項分析和優化
1、使用了過大的 WXML 節點數目

得分標准:頁面 WXML 節點少於 1000 個,節點樹深度少於 30 層,子節點數不大於 60 個。
頁面節點指標的意義在於,過大的節點數,過多過深的節點組成,都會增加內存使用,樣式重排時間更長,影響體驗。
現有節點2500+,想要進行優化,首先需要了解頁面各個模塊的節點數分布。
如何統計每個模塊的節點數呢?可以使用「控制變量法」,利用性能評測工具中,節點數超過1000時會列出節點總數的能力,我們可以在總指標超過1000的情況下,每次隱藏一個模塊:
目標模塊節點數 = 原總節點數 - 當前節點數
(實測節點數會有小范圍浮動,可以測3次取平均值)
首頁的模塊分析圖如下:

(第一屏) (第二屏)
簡化數據如下:

觀察列表可以得到兩個信息:首頁分為展示狀態互斥的第一屏和第二屏;列表模塊的節點數是大頭。
因此,我們得到優化的兩個方向:
- 頁面元素按需加載,不展示時不渲染
- 長列表減少元素個數
第一個優化項可以通過變量控制組件顯示隱藏,按需加載卸載。
第二個優化項首先想到的是減少列表接口分頁數值,比如一次請求20條數據改為請求5條。但是如果接口不支持自定義分頁,還可以實現更小的分頁拉取嗎?
那就自己寫一個分頁方法的代理吧~
思路如下:

上方為原始請求,每次20條數據,下方為代理請求的實現,每次返回5條。灰色虛線框是真實的請求數據動作,通過維護一個全量數據,需要哪頁取哪頁,這是示例代碼:

通過以上兩個優化,可以成功的把首頁的頁面節點數瘦身一下了,最后我們成功達到 wxml 節點總數不大於1000的目標。
2、存在圖片太大而有效顯示區域較小

得分標准:圖片寬高乘積 <= 實際顯示寬高乘積 * (設備像素比 ^ 2)
簡單理解是圖片尺寸太大而展示尺寸太小,導致浪費網絡請求時間和內存資源。
解決方案:cdn服務商一般都支持通過參數獲取不同尺寸的圖片,前端可以包裝一個公共方法,根據頁面元素尺寸拉取合適大小的圖片。
此外,補充一下圖片體積的內容,除了關注圖片尺寸,具體的體積大小其實更值得關注,有以下兩個點可以了解下:
-
圖片類型的選擇大有文章,jpg/png/gif 還有 webp 應該怎么選呢?先放一張 google 的圖

這張圖里未考慮 webp,加上 webp 其他類型競爭力瞬間不足了,移動端 androd 支持率基本可用,可以考慮根據設備類型漸進式使用:

-
利用一些壓縮技術對圖片進行壓縮,png 推薦 https://tinypng.com/ ,壓縮尺寸可觀,但對圖片顯示質量影響甚微。
3、存在可點擊元素的響應區域過小

得分標准:可點擊元素的寬高都不小於 20px
移動端操作全靠手指,過小的交互區域會帶來不好的體驗,可以通過增大元素響應熱區的方式來優化,以下方式都可以:
padding- 透明的
border box-shadow
4、對網絡請求做必要的緩存
得分標准:3 分鍾以內同一個url請求不出現兩次回包大於 128KB 且一模一樣的內容
這一項的理由是,發起網絡請求總會讓用戶等待,可能造成不好的體驗,應盡量避免多余的請求,比如對同樣的請求進行緩存。
優化方式:
- 善用小程序的 storage 能力,做好更新和過期管理后,盡可能緩存請求到的數據。
- 針對確實需要多次請求的日志類接口,可以通過在參數內添加隨機數或者時間戳的方式進行區分,避免誤判。
5、存在短時間內發起太多的請求
得分標准:通過wx.request發起的耗時超過 300ms 的請求並發數不超過 10 個。
不同於上一項,這一項關注的是接口並發數:
wx.request(HTTP 連接)的最大並發限制是 10 個wx.connectSocket(WebSocket 連接)的最大並發限制是 5 個
優化方式:
- 計算邏輯后移, 接口聚合
- 對於職責類似的網絡請求,最好采用節流的方式,先在一定時間間隔內收集數據,再合並到一個請求體中發送給服務端
6、存在未綁定在wxml上的變量

得分標准:setData傳入的所有數據都在模板渲染中有相關依賴
這一項考察的是 data 冗余的問題,小程序設計了渲染和邏輯分離的雙線程,兩邊通訊通過 evaluateJavascript 轉換字符串再進行拼接實現,需要非常小心兩個線程之間通訊的數據量。因此,未綁定wxml的變量,最好優化成不使用 setData。
根據使用場景,可以做的優化有:
- 與頁面展示無關的內部變量,可以掛載在組件實例上,比如維護一個
this.privateData對象 - 使用小程序新版本支持的「純數據字段」:該字段不會被傳遞到 wxml 內,配置正則划定它的匹配范圍,可以正常使用
setData方法,具體用法參見文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/pure-data.html
但是,如果你像我一樣遇到上面策略無法覆蓋的場景呢?
- 需要修改舊代碼,配置純數據字段的正則影響太大
- 京喜首頁使用了 Taro 做多端適配,Taro 編譯復雜邏輯的數組后會出現「影子變量」去代理邏輯,原本的數組變量被架空導致扣分
那么還有一個終極 hack 的方法:

這樣 list 會被判斷為有綁定節點,就不會扣分了
7、發起太多的圖片請求
得分標准:同域名耗時超過 100ms 的圖片請求並發數不超過 20 個
最后這一項也是圖片相關,發起太多圖片請求會觸發瀏覽器並行加載的限制,可能導致圖片加載慢,用戶一直處於等待中。
優化方式:
-
雪碧圖
-
圖片懶加載:小程序
Image組件支持通過配置lazy-load參數來實現懶加載(https://developers.weixin.qq.com/miniprogram/dev/component/image.html ),具體判定邏輯是圖片進入上下三屏就開始加載。如果需要更可控的實現,可以自己構建組件來處理。
總結
做完這些優化,再測一下體驗評分:

以上就是京喜首頁在小程序體驗評分優化方面進行的實踐內容了。
總結一下,小程序性能評分可以從指標和實際數據上給我們的項目優化提供一些建議,本文主要從評分角度去分析了各種優化可能,希望能為各位小程序開發者帶來參考價值。
參考資料
[1] 小程序開發文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/#小程序簡介
[2] Images: Your easiest page speed win: https://searchengineland.com/images-easiest-page-speed-win-269742
[3] Tiny Png: https://tinypng.com/
