微信官方文檔:性能與體驗(yàn)
啟動性能
-
代碼包體積優(yōu)化,合理使用分包加載
- 承載更多功能:小程序單個代碼包的體積上限為2M荆残,使用分包可以提升小程序代碼包總體積上限总放,承載更多的功能與服務(wù)
- 降低代碼包下載耗時:使用分包后可以顯著減少啟動時需要下載的代碼包大小配乱,在不影響功能正常使用的前提下,有效降低啟動耗時
- 降低小程序代碼注入耗時:使用分包可以避免不必要的組件和頁面初始化
- 降低內(nèi)存占用:分包能夠?qū)崿F(xiàn)頁面于毙、組件和邏輯較粗粒度的按需加載敦冬,從而降低內(nèi)存的占用
- 分包的擴(kuò)展功能,獨(dú)立分包望众,分包預(yù)下載匪补,分包異步化
-
避免非必要的全局自定義組件和插件
如果自定義組件只在某個分包的頁面中使用伞辛,應(yīng)定義在頁面的配置文件中
如果插件只在某個分包中使用烂翰,僅在分包中引用插件 -
控制代碼包內(nèi)的資源文件
小程序代碼包在下載時會使用ZSTD算法進(jìn)行壓縮夯缺,圖片、音頻甘耿,視頻踊兜、字體等資源文件會占用較多代碼包體積,并且通常難以進(jìn)一步被壓縮佳恬,對于下載耗時的影響較大捏境,所以,這類文件盡可能的部署到CDN毁葱,并使用URL引入垫言,建議在代碼包內(nèi)的圖片只包含一些體積小的圖標(biāo)
及時清理無用代碼和資源
代碼注入優(yōu)化(按需注入,用時注入)
啟動過程中減少同步API的調(diào)用(getSystemInfo倾剿、getStorageSync)
避免啟動過程進(jìn)行復(fù)雜運(yùn)算
-
首屏渲染優(yōu)化
- 使用按需注入和用時注入筷频,減少需要初始化的組件數(shù)量
- 啟用初始渲染緩存,可以在非首次啟動時前痘,提前將頁面渲染結(jié)果展示給用戶
- 避免引用未使用的自定義組件
頁面渲染時凛捏,會初始化在當(dāng)前頁面配置和全局配置通過usingComponents引用的自定義組件,以及組件所依賴的其他自定義組件芹缔,當(dāng)組件不被使用時坯癣,應(yīng)及時從usingComponents中移除
精簡首屏數(shù)據(jù)
首頁渲染的耗時和頁面的復(fù)雜度正相關(guān),對于復(fù)雜頁面可以選擇進(jìn)行漸進(jìn)式的渲染最欠,根據(jù)頁面內(nèi)容優(yōu)先級示罗,對于非關(guān)鍵部分或者不可見的部分進(jìn)行延遲更新
此外,與視圖層渲染無關(guān)的數(shù)據(jù)應(yīng)盡量不要放在data中芝硬,避免影響頁面渲染時間提前首屏數(shù)據(jù)請求
猶豫網(wǎng)絡(luò)請求需要相對較長的時間蚜点,建議在onload或者更早的時機(jī)發(fā)起網(wǎng)絡(luò)請求,而不應(yīng)該等待onready之后
- 數(shù)據(jù)預(yù)拉瘸橙 :小程序冷啟動時禽额,由客戶端通過微信后臺提前向三方服務(wù)器拉取業(yè)務(wù)數(shù)據(jù),減少用戶等待時間
- 周期性更新:未打開小程序的情況下皮官,提前從三方服務(wù)器拉取數(shù)據(jù)脯倒,減少用戶等待時間
- 緩存請求數(shù)據(jù),通過本地緩存的數(shù)據(jù)進(jìn)行渲染視圖
- 使用骨架屏捺氢,灰色的區(qū)塊大致勾勒輪廓藻丢,避免展示空白頁面,提升用戶等待意愿
運(yùn)行時性能
-
合理使用setData
setData的流程
1)邏輯層虛擬DOM樹的遍歷和更新摄乒,會觸發(fā)組件生命周期和observer等
2)將data從邏輯層傳輸?shù)揭晥D層
3)視圖層虛擬DOM樹的更新悠反、真實(shí)DOM元素的更新并觸發(fā)頁面渲染更新-
數(shù)據(jù)通信
對于第2步残黑,由于小程序的邏輯層和視圖層是兩個獨(dú)立的運(yùn)行環(huán)境、分屬不同的線程或進(jìn)程斋否,不能直接進(jìn)行數(shù)據(jù)共享梨水,需要進(jìn)行數(shù)據(jù)的序列化、跨線程/進(jìn)程的數(shù)據(jù)傳輸茵臭、數(shù)據(jù)的反序列化疫诽,因此數(shù)據(jù)傳輸過程是異步的、非實(shí)時的
使用建議
1)data應(yīng)只包括渲染相關(guān)的數(shù)據(jù)旦委,setData的方式更新渲染無關(guān)的字段奇徒,會出發(fā)額外的渲染流程,或增加傳輸?shù)臄?shù)據(jù)量缨硝,影響渲染耗時
2)頁面或組件的data字段摩钙,應(yīng)用來存放和頁面或組件渲染相關(guān)的數(shù)據(jù)(即直接在wxml中出現(xiàn)的字段)
3)頁面或組件渲染間接相關(guān)的數(shù)據(jù)可以設(shè)置為純數(shù)據(jù)字段,key使用setData設(shè)置并使用observers監(jiān)聽變化
4)頁面或組件渲染無關(guān)的數(shù)據(jù)查辩,應(yīng)掛在非data的字段下
5)避免在data中包含渲染無關(guān)的業(yè)務(wù)數(shù)據(jù)
6)避免使用data在頁面或組件方法間進(jìn)行數(shù)據(jù)共享
7)避免濫用純數(shù)據(jù)字段來保存可以使用非data字段保存的數(shù)據(jù)
8)僅在需要進(jìn)行頁面內(nèi)容更新時調(diào)用setData
9)對連續(xù)的setData調(diào)用盡可能的進(jìn)行合并
10)選擇合適的setData范圍胖笛,組件的setData只會引起當(dāng)前組件和子組件的更新,對于需要頻繁更新的頁面元素宜肉,可以封裝為獨(dú)立組建匀钧,在組建內(nèi)部進(jìn)行setData,必要時可以使用CSS contain屬性限制計(jì)算布局谬返、樣式和繪制等范圍
11)setData應(yīng)只傳發(fā)生變化的數(shù)據(jù)之斯,建議以數(shù)據(jù)路徑形式鋼鞭數(shù)組中某一項(xiàng)或?qū)ο蟮哪硞€屬性,而不是每次更新整個對象
12)頁面切后臺后的更新操作遣铝,應(yīng)盡量避免佑刷,或延遲到頁面onShow后延遲進(jìn)行
13 )控制setData的頻率,每次setData都會觸發(fā)邏輯層虛擬DOM樹的遍歷和更新酿炸,也可能會導(dǎo)致觸發(fā)一次完整的頁面渲染流程瘫絮。過于頻繁(毫秒級)的調(diào)用setData,會導(dǎo)致一下后果:
邏輯層JS線程持續(xù)繁忙填硕,無法正常響應(yīng)用戶操作的事件麦萤,也無法正常完成頁面切換
視圖層JS線程持續(xù)處于忙碌狀態(tài),邏輯層->視圖層通信耗時上升扁眯,視圖層收到消息的延時較高壮莹,渲染出現(xiàn)明顯延遲
視圖層無法及時響應(yīng)用戶操作,用戶滑動頁面時干到明顯卡頓姻檀,操作反饋延遲命满,用戶操作時間無法及時傳遞到邏輯層,邏輯層亦無法及時將操作處理結(jié)果傳遞到視圖層 -
渲染性能優(yōu)化
- scroll事件觸發(fā)頻率很高
- 非必要不監(jiān)聽scroll事件绣版,
- 在實(shí)現(xiàn)與滾動相關(guān)動畫時胶台,優(yōu)先考慮滾動驅(qū)動動畫(僅<scroll-view>)或wxs響應(yīng)事件
- 不需要監(jiān)聽事件時歼疮,不要保留onPageScroll空函數(shù)
- 避免在scroll事件監(jiān)聽函數(shù)中執(zhí)行復(fù)雜邏輯
- 避免在scroll事件監(jiān)聽中頻繁調(diào)用setData或同步API
- 需要監(jiān)控元素曝光情況,建議使用節(jié)點(diǎn)布局相交狀態(tài)監(jiān)聽IntersectionObserver推斷某些節(jié)點(diǎn)是否可見诈唬,有多大比例可見(避免監(jiān)聽onPageScroll中持續(xù)調(diào)用selectQuery判斷)
- 建議一個頁面wxml節(jié)點(diǎn)數(shù)量少于1000個韩脏,節(jié)點(diǎn)樹深度少于30層,子節(jié)點(diǎn)數(shù)不大于60個
- 對于比較復(fù)雜的數(shù)據(jù)對象讯榕,建議在onload或created時手動賦值到this上骤素,而不是page構(gòu)造時的參數(shù)傳入
- 選擇高性能的動畫實(shí)現(xiàn)方式
優(yōu)先使用CSS漸變匙睹、CSS動畫愚屁、或小程序框架提供的其他動畫實(shí)現(xiàn)方式完成動畫
在一些復(fù)雜場景下,如果上述方式不能滿足痕檬,可以使用wxs響應(yīng)事件動態(tài)調(diào)整節(jié)點(diǎn)的style屬性做到動畫效果霎槐。
避免通過連續(xù)setData實(shí)現(xiàn)動畫,不可避免梦谜,則盡可能改成自定義組件中的setData -
頁面切換優(yōu)化
- 頁面切換時丘跌,會先調(diào)用前一個頁面的onHide/onUnload方法,所以避免在onHide/onUnload執(zhí)行耗時操作
- 頁面預(yù)加載
-
資源加載優(yōu)化
- 控制圖片資源大小
- 避免濫用image組件的widthFix和heightFix唁桩,盡量預(yù)先指定圖片尺寸闭树,避免加載完成后二次調(diào)整尺寸
-
內(nèi)存優(yōu)化
- 合理使用分包
- 使用按需注入和用時注入
- 內(nèi)存分析
- 處理內(nèi)存告警,必要時使用wx.onMemoryWarning監(jiān)聽內(nèi)存告警時間荒澡,進(jìn)行必要的內(nèi)存清理报辱,釋放一些暫時不用的組件或者js對象
- 內(nèi)存泄露
1)小程序長期持有頁面實(shí)例,導(dǎo)致頁面和引用組件無法正常銷毀(事件監(jiān)聽持有頁面this单山,頁面實(shí)例唄頁面外變量或者全局變量引用碍现,頁面實(shí)例唄異步回調(diào)長時間引用等)*
2)事件監(jiān)聽未解綁
3)未清理的定時器