wordpress百度自動推送安裝失敗百度灰色詞優(yōu)化排名
一、丟幀問題概述
????????應用丟幀通常指的是在應用程序的界面繪制過程中,由于某些原因?qū)е陆缑胬L制的幀率下降,從而造成界面卡頓、動畫不流暢等問題。以60Hz刷新率為例子,想要達到每秒60幀(即60fps)的流暢體驗,每一幀需要在16.7ms內(nèi)完成,如果超過16.7ms未完成渲染,就可能會出現(xiàn)丟幀。
二、丟幀問題原理
????????在HarmonyOS中,圖形系統(tǒng)采用了統(tǒng)一渲染的模式,遵循著一個典型的流水線模式,以90Hz刷新率為例,每個Vsync周期是11.1ms,整個過程如下圖所示。如果是60Hz,每個Vsync的周期是16.7ms;如果是120Hz,則每個Vsync的周期是8.3ms。
????????
????????在整個渲染流程中,首先是由應用側(cè)響應用戶的屏幕點擊等輸入事件,由應用側(cè)處理完成后再提交給Render Service,由Render Service協(xié)調(diào)GPU等資源處理后,再將最終的圖像統(tǒng)一送到屏幕上進行顯示。
- 應用側(cè)(App)處理用戶的屏幕點擊等輸入事件,生成當前界面描述的數(shù)據(jù)結(jié)構(gòu)。其中,界面描述數(shù)據(jù)包括UI元素的位置,大小,資源,UI元素的繪制指令,動效屬性等。
- RenderService(渲染服務部件)是圖形棧中負責界面內(nèi)容繪制的模塊,其主要職責就是對接ArkUI框架,支撐ArkUI應用的界面顯示,包括控件、動效等UI元素。RenderService的RenderThread線程在Vsync下觸發(fā)UI繪制,繪制過程包含3個階段:Animation動效,Draw描畫和Flush提交。
- Display是顯示屏幕的抽象概念,可以是實際的物理屏也可以是虛擬屏。
????????其中應用側(cè)的渲染流程如下圖所示,了解ArkUI的渲染流程有助于我們定位應用側(cè)的卡頓問題出現(xiàn)在哪個環(huán)節(jié):
?????????
- Animation:動畫階段,在動畫過程中會修改相應的FrameNode節(jié)點觸發(fā)臟區(qū)標記,在特定場景下會執(zhí)行用戶側(cè)ets實現(xiàn)自定義動畫;
- Events:事件處理階段,比如手勢事件處理。在手勢處理過程中也會修改FrameNode節(jié)點觸發(fā)臟區(qū)標記,在特定場景下會執(zhí)行用戶側(cè)ets 實現(xiàn)自定義事件;
- UpdateUI:自定義組件(@Component)在首次創(chuàng)建掛載或者狀態(tài)變量變更時會標記為需要rebuild狀態(tài),在下一次Vsync過來時會執(zhí)行rebuild流程,rebuild流程會執(zhí)行程序UI編碼,通過調(diào)用View的方法生成相應的組件樹結(jié)構(gòu)和屬性樣式修改任務。
- Measure:布局包裝器執(zhí)行相關(guān)的大小測算任務。
- Layout:布局包裝器執(zhí)行相關(guān)的布局任務。
- Render:繪制任務包裝器執(zhí)行相關(guān)的繪制任務,執(zhí)行完成后會標記請求刷新RSNode繪制
- SendMessage:請求刷新界面繪制。
?????????在整個處理流程中,應用側(cè)和Render Service側(cè)都有可能出現(xiàn)卡頓導致最終用戶觀測到丟幀的可能,我們分別將這兩種情況命名為AppDeadlineMissed和RenderDeadlineMissed。一般而言,前者可能是應用邏輯處理編碼不夠高效導致的,后者可能是界面結(jié)構(gòu)過于復雜或者GPU負載過大等原因?qū)е碌?。這兩個故障模型通過Frame模板都可以直觀地看到。相應的故障模型如下面兩幅圖所示。
????????應用卡頓導致丟幀的故障模型:
?????????
????????Render Service卡頓導致丟幀的故障模型:?
????????? ? ? ??
三、丟幀問題思路分析?
????????丟幀問題處理流程:
????????
四、處理丟幀問題步驟
? ? ? ? 1、識別卡頓
????????首先使用AppAnalyzer檢測應用是否存在性能問題,如果檢測存在丟幀問題,然后使用Frame Profiler、SmartPerf Host等工具錄制Trace,查看應用平均幀率、丟幀率等,同時查看丟幀發(fā)生的位置。
? ? ? ? 2、分析丟幀原因
????????首先查看CPU調(diào)用判斷系統(tǒng)是否存在異常,如果判斷系統(tǒng)異常開發(fā)可以通過在線提單的方式進行反饋;如果系統(tǒng)沒有異常,可以繼續(xù)分析Trace查看卡頓幀的詳細信息。最后查看函數(shù)調(diào)用棧,查看是否存在耗時函數(shù)。
? ? ? ? 3、選擇優(yōu)化方案
????????根據(jù)步驟2分析的丟幀原因,選擇適合的優(yōu)化方案。
? ? ? ? 4、驗證優(yōu)化效果
????????優(yōu)化完成后需要重新測試驗證丟幀問題是否得到解決,這里可以再次通過步驟1來確認優(yōu)化效果。
五、常見丟幀問題
? ? ? ? 1、自定義動畫丟幀問題
????????在播放動畫或者生成動畫時,畫面產(chǎn)生停滯而導致幀率過低的現(xiàn)象,稱為動畫丟幀。
????????播放動畫時,系統(tǒng)需要在一個刷新周期內(nèi)完成動畫變化曲線的計算,完成組件布局繪制等操作。建議使用系統(tǒng)提供的動畫接口,只需設置曲線類型、終點位置、時長等信息,就能夠滿足常用的動畫功能,減少UI主線程的負載。
? ? ? ? 2、布局嵌套過深
????????視圖的嵌套層次會影響應用的性能。在屏幕刷新率為120Hz的設備上,每8.3ms刷新一幀,如果視圖的嵌套層次多,可能會導致沒法在8.3ms內(nèi)完成一次屏幕刷新,就會造成丟幀卡頓,影響用戶體驗。因此推薦開發(fā)者移除多余的嵌套層次,使用相對布局 (RelativeContainer),縮短組件刷新耗時。
? ? ? ? 3、UI冗余刷新
????????自定義組件中的變量被狀態(tài)裝飾器(@State,@Prop等)裝飾后成為狀態(tài)變量,而狀態(tài)變量的改變會引起使用該變量的UI組件渲染刷新。狀態(tài)變量的不合理使用可能會帶來冗余刷新等性能問題。開發(fā)者可以使用狀態(tài)變量組件定位工具(hidumper)獲取狀態(tài)管理相關(guān)信息,例如自定義組件擁有的狀態(tài)變量、狀態(tài)變量的同步對象和關(guān)聯(lián)組件等,了解狀態(tài)變量影響UI的范圍,寫出高性能應用。
? ? ? ? 4、主線程中執(zhí)行冗余和耗時操作
????????應避免在主線程中執(zhí)行冗余與易耗時操作,否則可能會阻塞UI渲染,引發(fā)界面卡頓或掉幀現(xiàn)象,特別是在高頻回調(diào)中執(zhí)行耗時操作。
六、丟幀問題優(yōu)化建議
- 盡量減少布局的嵌套層數(shù),合理使用布局,使用相對布局來減少層級。
- 使用組件復用減少組件的重復創(chuàng)建與渲染。
- 合理管理狀態(tài)變量,精準控制組件的更新范圍,避免冗余刷新。
- 使用LazyForEach加載長列表,長列表的優(yōu)化。
- 使用系統(tǒng)提供的動畫接口,減少動畫丟幀。
- 優(yōu)化主線程中冗余和耗時操作,