語言層面的優化
使用明確的數據類型,避免使用模糊的數據類型,例如ESObject。
使用AOT模式
AOT就是提前編譯,將字節碼提前編譯成機器碼,這樣可以充分優化,從而加快執行速度。
未啟用AOT時,一邊運行一邊進行機器碼的生成。
開啟AOT后,設備能直接運行已經提前優化過的機器碼,大大提高執行速度。
應用啟動優化
應用階段劃分:
- 第一階段:應用進程的創建和初始化
- 第二階段:App和Ability的初始化
- 第三階段:Ability生命周期
- 第四階段:加載繪制首頁
每個啟動階段的優化策略:
- 第一階段優化:設置合適分辨率的應用圖標
- 第二階段優化:減少首頁Ability或者Page中import的模塊數量,不是首頁必須的模塊可以使用動態異步加載,如await import(‘Page’)
- 第三階段優化:Ability生命周期方法中,對于耗時操作進行異步處理
- 第四階段優化:延遲加載,減少不必要的首頁內容。例如使用LazyForEach替換ForEach
LazyForEach替換ForEach
LazyForEach是一種懶加載的模式,在循環繪制組件時能顯著提升頁面的加載速度。結合cacheCount方法能控制列表的緩存數量,實現更優的滑動體驗。
減少丟幀卡頓
- 避免在主線程上執行耗時操作:將耗時操作放在TaskPool或者Worker等后臺進程中執行,從而防止主線程負載過高。
- 減少渲染進程的冗余開銷:使用資源圖代替繪制、合理使用renderGroup、尺寸位置使用整數。
- 減少試圖嵌套層級
- 組件復用
- 控制狀態變量關聯的組件數量
- 在對象上謹慎使用狀態變量進行關聯
優化案例
組件轉場動畫推薦使用transition,不推薦使用animateTo方法。
減少animateTo方法的使用數量,一起變更比分開變更更加高效。
多次animateTo時統一更新狀態變量,減少多次更新狀態變量導致的開銷。
使用RenderGroup可以緩存組件及其子組件的繪制,從而降低繪制負載優化渲染性能。適合沒狀態綁定的不變組件,如果有狀態綁定,當狀態變化時緩存就是失效了。
使用@Reusable標記復用組件,適用頻繁創建和銷毀的組件,或反復切換條件渲染的控制分支且控制分支中的組件子樹結構相同。
不推薦使用更新單個狀態變量的形式控制多個組件的更新(命令式);
推薦使用狀態變量和組件一對一綁定的方式,以數據變更驅動組件的刷新(聲明式);
合理控制狀態變量更新范圍,避免關聯刷新大量組件。關聯變化較大的狀態變量可以通過對象組合成一個狀態變量,針對渲染成本較高的組件建議使用獨立的狀態變量進行關聯。
理解@Prop和@ObjectLink的區別:@Prop是深拷貝關聯,@ObjectLink是淺拷貝關聯,因此優先推薦使用@ObjectLink的方式,從而減少系統內存開銷。
性能調優工具
Profile調優工具
合理使用布局
組件布局屬性(width、height、padding、margin等)大小發生變化會導致受影響的整個組件樹重新更新,而非布局屬性(Color、BackgroundColor、opacity等)的變化僅影響組件自身。這一點跟Web界面的渲染機制類似,因此我們在更新界面元素時,盡量減少布局屬性的變化,防止影響整個組件的重新渲染。如果某些組件需要經常變化,可以將組件置于一個固定布局(這個布局內,布局屬性固定)內,將影響固定在這個固定布局內部,從而減少對其他組件的影響。
精簡節點數
- 移除冗余節點
- 使用扁平化布局減少節點數
扁平化方法:通過將嵌套結構攤開,減少中間節點,從而提升渲染速度。常用方法有:
- 通過RelativeContainer 相對布局實現扁平化
- 通過錨點定位實現扁平化
- 通過Grid布局實現扁平化
利用布局邊界減少計算
對于能夠在初期給定寬高的組件,在進行UI描述時盡量給定寬高數值,能夠減少由于容器尺寸變化造成的重新測算過程的性能。
合理控制元素的顯示與隱藏
首次繪制時,if會根據是否為true決定是否創建組件,而visibility組件無論是否顯示都要創建組件。
再次顯示時,if由于首次沒有創建組件,再次顯示時會創建組件,并經過Measure和Layout階段。而visibility組件已經創建過,只需要經過Measure和Layout階段。
- 只有初始的一次渲染或者交互次數很少的情況下,建議使用if條件判斷來控制元素的顯示與隱藏效果,對于內存有較大提升。
- 如果會頻繁響應顯示與隱藏的交互效果,建議使用切換Visibility.None和Visibility.Visible來控制元素顯示與隱藏,提高性能。