HarmonyOS 性能優(yōu)化
如何合理使用動效來獲得更好的性能
-
組件轉(zhuǎn)場動畫使用 transition:
- 推薦使用轉(zhuǎn)場動畫(transition)而不是組件動畫(animateTo),因為 transition 只需要在條件改變時更新一次,而 animateTo 需要在動畫前后做兩次屬性更新,導(dǎo)致性能開銷更大。
- 反例:通過改變透明度屬性并使用 animateTo 來隱藏和顯示組件。
- 正例:直接使用 transition 動畫,通過改變透明度實現(xiàn)組件的出現(xiàn)與消失。
-
組件布局改動時使用圖形變換屬性動畫:
- 當(dāng)需要改動組件的布局顯示時,推薦使用圖形變換屬性(如平移、旋轉(zhuǎn)、縮放)而不是改動布局屬性(如 width、height、layoutWeight),因為圖形變換不會重新觸發(fā)布局,從而減少性能開銷。
- 反例:通過設(shè)置布局屬性 width 和 height 來改變組件大小。
- 正例:通過設(shè)置圖形變換屬性 scale 來改變組件大小。
-
動畫參數(shù)相同時使用同一個 animateTo:
- 如果多個屬性需要使用相同的動畫參數(shù)進(jìn)行動畫處理,應(yīng)該將它們合并到一個 animateTo 閉包中,以減少組件更新的次數(shù)。
- 反例:將相同動畫參數(shù)的狀態(tài)變量更新放在不同的動畫閉包中。
- 正例:將相同動畫參數(shù)的動畫合并在一個動畫閉包中。
-
多次 animateTo 時統(tǒng)一更新狀態(tài)變量:
- 在執(zhí)行多個 animateTo 之前,應(yīng)該統(tǒng)一更新狀態(tài)變量,避免在執(zhí)行動畫之間產(chǎn)生冗余的狀態(tài)更新。
- 反例:在兩個 animateTo 之間更新狀態(tài)變量。
- 正例 1:在 animateTo 之前使用原始狀態(tài),讓動畫從原始狀態(tài)過渡到指定狀態(tài)。
- 正例 2:在 animateTo 之前顯式指定所有需要動畫的屬性初值,統(tǒng)一更新到節(jié)點中,然后再執(zhí)行動畫。
應(yīng)用性能提升
1. 使用數(shù)據(jù)懶加載
在處理長列表數(shù)據(jù)時,傳統(tǒng)的循環(huán)渲染方式會一次性加載所有列表元素,這會導(dǎo)致頁面啟動時間過長,影響用戶體驗,并增加服務(wù)器壓力。為了解決這個問題,推薦使用 DataSource 來實現(xiàn)數(shù)據(jù)懶加載技術(shù)。通過懶加載,只有當(dāng)數(shù)據(jù)進(jìn)入可視區(qū)域時才加載和渲染,這樣可以顯著提高頁面的響應(yīng)速度和性能。
2. 設(shè)置 List 組件的寬高
在使用 Scroll 容器組件嵌套 List 組件加載長列表時,如果沒有指定 List 的寬高尺寸,List 將會布局其所有子組件,這會導(dǎo)致性能問題。通過設(shè)置 List 的寬高,可以確保只布局 List 顯示區(qū)域內(nèi)的子組件,從而提高性能。
Scroll 嵌套 List 時:
- List 沒有設(shè)置寬高,會布局 List 的所有子組件。
- List 設(shè)置寬高,會布局 List 顯示區(qū)域內(nèi)的子組件。
- List 使用 ForEach 加載子組件時,無論是否設(shè)置 List 的寬高,都會加載所有子組件。
- List 使用 LazyForEach 加載子組件時,沒有設(shè)置 List 的寬高,會加載所有子組件,設(shè)置了 List 的寬高,會加載 List 顯示區(qū)域內(nèi)的子組件。
3. 使用條件渲染替代顯隱控制
使用 visibility 屬性控制組件的顯隱狀態(tài)時,即使組件不可見,它仍然會被重新創(chuàng)建,這會造成性能損耗。通過使用 if 條件渲染,可以避免組件的重新創(chuàng)建過程,從而提升性能。
4. 使用 Column/Row 替代 Flex
Flex 容器組件在默認(rèn)情況下存在 shrink 屬性,這可能導(dǎo)致二次布局,影響頁面渲染性能。通過使用 Column 和 Row 組件替代 Flex,可以避免二次布局帶來的性能問題。
5. 減少應(yīng)用滑動白塊
在應(yīng)用中,滑動白塊是一個常見的性能問題。通過增大 List/Grid 控件的 cachedCount 參數(shù),可以預(yù)加載更多的 item,減少白塊的出現(xiàn)。同時,如果需要請求網(wǎng)絡(luò)圖片,可以提前下載內(nèi)容,以減少滑動時的白塊現(xiàn)象。
狀態(tài)管理優(yōu)化
以下是文檔中提到的一些關(guān)鍵點:
- 使用@ObjectLink 代替@Prop 減少不必要的深拷貝:
在父子組件間傳遞數(shù)值時,如果子組件不需要改變狀態(tài)變量的值,使用@ObjectLink 比@Prop 更優(yōu),因為@Prop 會導(dǎo)致深拷貝,增加性能開銷。
- 不使用狀態(tài)變量強行更新非狀態(tài)變量關(guān)聯(lián)組件:開發(fā)者應(yīng)避免通過改變自定義的 UI 狀態(tài)變量來帶動常規(guī)變量的更新,而應(yīng)將相關(guān)成員變量用@State 裝飾,以便框架能夠檢測狀態(tài)變化并觸發(fā) UI 更新。
- 精準(zhǔn)控制狀態(tài)變量關(guān)聯(lián)的組件數(shù):建議每個狀態(tài)變量關(guān)聯(lián)的組件數(shù)少于 20 個,以減少不必要的組件刷新,提高效率。
- 合理控制對象類型狀態(tài)變量關(guān)聯(lián)的組件數(shù)量:如果一個復(fù)雜對象被定義為狀態(tài)變量,需要合理控制其關(guān)聯(lián)的組件數(shù),避免“冗余刷新”。
- 查詢狀態(tài)變量關(guān)聯(lián)的組件數(shù):可以使用 HiDumper 工具查看狀態(tài)變量關(guān)聯(lián)的組件數(shù),進(jìn)行性能優(yōu)化。
- 避免在 for、while 等循環(huán)邏輯中頻繁讀取狀態(tài)變量:應(yīng)該在循環(huán)外面讀取狀態(tài)變量,避免在循環(huán)邏輯中頻繁讀取,以提高性能。
避免冗余操作
- 避免在高頻回調(diào)中進(jìn)行冗余操作:在處理如滾動事件、觸摸事件等高頻回調(diào)時,應(yīng)避免在回調(diào)函數(shù)內(nèi)部執(zhí)行冗余的日志記錄、Trace追蹤和耗時操作。這些操作會嚴(yán)重影響應(yīng)用的性能和響應(yīng)速度。
- 刪除冗余Trace和日志打印:在開發(fā)階段,日志和Trace追蹤是重要的輔助工具,但在發(fā)布版本中應(yīng)移除這些冗余的輸出,以避免不必要的性能開銷。
- 避免設(shè)置冗余的系統(tǒng)回調(diào)監(jiān)聽:如果回調(diào)函數(shù)體內(nèi)不包含任何業(yè)務(wù)邏輯代碼,應(yīng)將其刪除。注冊但未使用的回調(diào)會消耗系統(tǒng)資源,影響程序運行效率。

浙公網(wǎng)安備 33010602011771號