Flutter優(yōu)化我們可以從以下幾方面入手

檢測工具 Flutter Inspector (debug模式下)

Flutter inspector 頁面

點(diǎn)擊左上角的圖標(biāo),進(jìn)入select widget model 模式,此時(shí)點(diǎn)擊相應(yīng)的widget,就可在頁面上顯示其具體的布局區(qū)域


select widget model
  • Highlight Repaints - 上圖右上角操作圖標(biāo)的倒數(shù)第二個(gè),若是widget發(fā)生重繪,就會(huì)改變顏色,據(jù)此發(fā)現(xiàn)頻繁重繪的區(qū)域


    Highlight Repaints
  • Highlight Oversizeded Images 上圖的右上角倒數(shù)第一個(gè),該功能會(huì)檢測出頁面中圖片實(shí)際大小大于顯示大小的視圖,并將圖片進(jìn)行倒置,便于發(fā)現(xiàn),如何優(yōu)化下邊下邊再講


    Highlight Oversizeded Images
Flutter支持Release、Profile、Debug編譯模式。
  1. Release模式,使用AOT預(yù)編譯模式,預(yù)編譯為機(jī)器碼,通過編譯生成對應(yīng)架構(gòu)的代碼,在用戶設(shè)備上直接運(yùn)行對應(yīng)的機(jī)器碼,運(yùn)行速度快,執(zhí)行性能好;此模式關(guān)閉了所有調(diào)試工具,只支持真機(jī)。
  2. Profile模式,和Release模式類似,使用AOT預(yù)編譯模式,此模式最重要的作用是可以用DevTools來檢測應(yīng)用的性能,做性能調(diào)試分析。
  3. Debug模式,使用JIT(Just in time)即時(shí)編譯技術(shù),支持常用的開發(fā)調(diào)試功能hot reload,在開發(fā)調(diào)試時(shí)使用,包括支持的調(diào)試信息、服務(wù)擴(kuò)展、Observatory、DevTools等調(diào)試工具,支持模擬器和真機(jī)。

開啟profile模式 VSCode launch.json中添加"flutterMode": "profile"

{
    // 使用 IntelliSense 了解相關(guān)屬性。 
    // 懸停以查看現(xiàn)有屬性的描述。
    // 欲了解更多信息,請?jiān)L問: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "flutter_push",
            "request": "launch",
            "type": "dart",
            "flutterMode": "profile"
        },
        
    ]
}

Performance Overlay(性能圖層)

showPerformanceOverlay: true,

return MaterialApp(
      showPerformanceOverlay: true,
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {'First': (context) => const PushFirstPage(), 'Second': (context) => const PushSecondPage(), 'Third': (context) => const PushThirdPage()},
    );
截屏2024-03-21 09.10.07.png

截屏2024-03-21 09.10.17.png

如上圖所示 藍(lán)色表示 正常幀,綠色表示當(dāng)前幀,紅色表示出現(xiàn)卡頓的幀,結(jié)合當(dāng)前頁面和操作 定位卡頓位置

CPU Profiler

定位耗時(shí)操作
首先要運(yùn)行在 profile 模式下
打開Flutter DevTools
搜索欄輸入>devtools,點(diǎn)擊 Dart: DevTools,并選擇瀏覽器打開


截屏2024-03-21 09.23.23.png

點(diǎn)擊record,就開始收集,之后點(diǎn)擊stop


截屏2024-03-21 09.26.55.png

橫向表示執(zhí)行時(shí)間
豎向表示 調(diào)用堆棧
由此分析耗時(shí)的方法

對于低端機(jī)型的耗時(shí)操作 可開啟新的線程處理


截屏2024-03-21 09.28.57.png

優(yōu)化

布局優(yōu)化

Flutter UI涉及到三棵樹

  • widget Tree 配置控件信息,不涉及渲染,更新代價(jià)低
  • elememt Tree widget和renderObject的粘合劑
  • RenderObject 真正負(fù)責(zé)渲染的樹,更新代價(jià)大

1、build() 不在build中執(zhí)行耗時(shí)操作,由于該方法調(diào)用的幾率極大,早期開發(fā)更新 都是通過調(diào)用build進(jìn)行的,可將耗時(shí)操作使用isolate實(shí)現(xiàn)
2、盡量將build中的widget的粒度拆小,可復(fù)用的模塊抽離,拆小力度后可使用 inherteWidget、GetX等按需更新,也增加了 代碼的可讀性
3,盡量使用const構(gòu)造器,特別是 一些通用的不更改的常量組件,比如空視圖,比如加載中
4、listview構(gòu)造的時(shí)候 盡量使用其 builder構(gòu)造器,盡量不使用children顯示視圖,builder是只渲染 顯示的部分

內(nèi)存優(yōu)化

1、const實(shí)例化,const會(huì)創(chuàng)建一個(gè)編譯時(shí)的常量,存在一個(gè)特殊的查詢列表里,僅分配一次內(nèi)存
2、檢測內(nèi)存消耗過高的圖標(biāo),上邊所示的Highlight Oversizeded Images即可檢測,針對大內(nèi)存的圖片 可自行展示大小,長列表大內(nèi)存圖片 可導(dǎo)致app崩潰,也可建立檢測機(jī)制,檢測列表圖片的大小 過高的話 上報(bào)大數(shù)據(jù),具體分析優(yōu)化


截屏2024-03-21 09.46.05.png

3、listview中有大量image的情況
listview為了保證滑動(dòng)的性能 會(huì)讓子widget保持活動(dòng)狀態(tài),這一點(diǎn)事通過AutomaticKeepAlive控制的,再次 向后滑動(dòng),為防止widget重新繪制,這個(gè)是由RepaintBoundaries 保證的,但是若是加載大量的圖片,就會(huì)消耗大量的內(nèi)存,最終可能會(huì)導(dǎo)致App崩潰


截屏2024-03-21 09.55.10.png

兩個(gè)屬性都設(shè)置為 false后,不可見的子widget就會(huì)被 自動(dòng)處理

4、降低customScrollView listView的預(yù)渲染合理值
默認(rèn)情況下 customscrollview除了渲染 屏幕顯示內(nèi)容外 還會(huì)渲染 上下各250區(qū)域的內(nèi)容,可根據(jù)每一個(gè)item的大小和是否是低端機(jī)調(diào)整預(yù)渲染區(qū)域的大小


截屏2024-03-21 09.59.33.png
綜合邏輯優(yōu)化

1、減少自定義的 微任務(wù)內(nèi)容,一般我們認(rèn)為 微任務(wù)多數(shù)是系統(tǒng)觸發(fā)的,但是我們也可以創(chuàng)建 比如Future.value,比如Future(() => null).then(() {})then中的任務(wù)就是微任務(wù),以保證future執(zhí)行完后立刻執(zhí)行then中的處理,再比如stream任務(wù),也可以自己創(chuàng)建微任務(wù) schedmicroTask,由于微任務(wù)的執(zhí)行優(yōu)先級(jí) 高于UI任務(wù),過多的微任務(wù),會(huì)占用cpu,使UI處理滯后,造成卡頓
避免以上情況 就需要按需使用 不顯示的頁面相應(yīng)的數(shù)據(jù)傳輸就停掉
2、盡可能的小粒度刷新,盡量不使用setstate刷新整個(gè)頁面,將builder中的視圖分成若干widget,按需刷新 可使用inheritWidget或是GetX

內(nèi)存移除的檢測

底層widget 一般是tabbarPage混入 WidgetsBindingObserver,
我們一般是使用這個(gè)類來檢測app的生命周期 包括 后臺(tái) 前臺(tái) 隨時(shí)可能退出,殺掉進(jìn)程的狀態(tài) 但是卻忽略了 這里的一個(gè)檢測 就是檢測內(nèi)存溢出的方法

/// Called when the system is running low on memory.
  ///
  /// This method exposes the `memoryPressure` notification from
  /// [SystemChannels.system].
  void didHaveMemoryPressure() { }

類似于IOS中 viewController中的檢測內(nèi)存溢出的回調(diào)方法- (void)didReceiveMemoryWarning,
我們可以在上述方法中進(jìn)行內(nèi)存的手動(dòng)釋放

/// 釋放圖片組件的緩存
DefaultCacheManager().emptyCache();
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容