中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

分析Flutter應用性能檢測與優化

發布時間:2021-11-04 16:57:04 來源:億速云 閱讀:175 作者:iii 欄目:web開發

這篇文章主要介紹“分析Flutter應用性能檢測與優化”,在日常操作中,相信很多人在分析Flutter應用性能檢測與優化問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”分析Flutter應用性能檢測與優化”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

圖層分析

Flutter運行模式

1、Debug

Debug模式可以在真機和模擬器上同時運行,此模式會打開所有的斷言,包括debugging信息、debugger aids(比如observatory)和服務擴展。優化了快速develop/run循環,但是沒有優化執行速度、二進制大小和部署。命令flutter run就是以這種模式運行的,通過sky/tools/gn --android或者sky/tools/gn --ios來構建應用的。

2、Release

Release模式只能在真機上運行,不能在模擬器上運行:會關閉所有斷言和debugging信息,關閉所有debugger工具。優化了快速啟動、快速執行和減小包體積。禁用所有的debugging aids和服務擴展。這個模式是為了部署給最終的用戶使用。命令flutter run --release就是以這種模式運行的,通過sky/tools/gn --android --runtime-mode=release或者sky/tools/gn --ios --runtime-mode=release來構建應用。

3、Profile

Profile模式只能在真機上運行,不能在模擬器上運行,基本和Release模式一致,除了啟用了服務擴展和tracing,以及一些為了最低限度支持tracing運行的東西(比如可以連接observatory到進程)。命令flutter run --profile就是以這種模式運行的,通過sky/tools/gn --android --runtime-mode=profile或者sky/tools/gn --ios --runtime-mode=profile來構建應用。

4、test

headless test模式只能在桌面上運行,基本和Debug模式一致,除了是headless的而且你能在桌面運行。命令flutter test就是以這種模式運行的,通過sky/tools/gn來build。

在實際開發中,應該用到上面所說的四種模式又各自分為兩種:一種是未優化的模式,供開發人員調試使用;一種是優化過的模式,供最終的開發人員使用。默認情況下是未優化模式,如果要開啟優化模式,build的時候在命令行后面添加--unoptimized參數。

不管是移動開發還是前端開發,對于性能問題分析的思路都是先分析并定位問題,Flutter也不例外,借助Flutter 提供的度量性能工具,我們可以快速定位代碼中的性能問題,而性能圖層就是幫助我們確認問題影響范圍的利器,它類似Android的圖層分析工具。

為了使用性能圖層,Flutter提供了分析(Profile)模式,與調試代碼可以通過模擬器在調試模式下找到代碼邏輯 Bug 不同,性能問題需要在發布模式下使用真機進行檢測。相比發布(Release)模式而言,調試模式增加了很多額外的檢查(比如斷言),這些檢查可能會耗費很多資源;更重要的是,調試模式使用 JIT (即時編譯)模式運行應用,代碼執行效率較低。這就使得調試模式運行的應用,無法真實反映出它的性能問題。

而另一方面,模擬器使用的指令集為 x86,而真機使用的指令集是 ARM,由于這兩種方式的二進制代碼執行行為完全不同,因此模擬器與真機的性能差異較大。一些 x86 指令集擅長的操作模擬器會比真機快,而另一些操作則會比真機慢,這也使得我們無法使用模擬器來評估真機才能出現的性能問題。

為了調試性能問題,我們需要在發布模式的基礎之上,為分析工具提供少量必要的應用追蹤信息,這就是分析模式。除了一些調試性能問題必須的追蹤方法之外,Flutter 應用的分析模式和發布模式的編譯和運行是類似的,只是啟動參數變成了 profile 而已。我們可以在 Android Studio 中通過菜單欄點擊 【Run】-【Profile 】‘main.dart’ 選項啟動應用,也可以通過命令行參數 flutter run --profile 運行 Flutter 應用。

渲染問題分析

在完成了應用啟動之后,接下來我們就可以利用 Flutter 提供的渲染問題分析工具,即性能圖層(Performance Overlay)來分析渲染問題了。性能圖層會在當前應用的最上層,以 Flutter 引擎自繪的方式展示 GPU 與 UI 線程的執行圖表,而其中每一張圖表都代表當前線程最近 300 幀的表現,如果 UI 產生了卡頓(跳幀),這些圖表可以幫助我們分析并找到原因,如下圖所示。

分析Flutter應用性能檢測與優化

上圖演示了性能圖層的展現樣式。其中,GPU 線程的性能情況在上面,UI 線程的情況顯示在下面,藍色垂直的線條表示已執行的正常幀,綠色的線條代表的是當前幀。

同時,為了保持 60Hz 的刷新頻率,GPU 線程與 UI 線程中執行每一幀耗費的時間都應該小于 16ms(1/60 秒)。在這其中有一幀處理時間過長,就會導致界面卡頓,圖表中就會展示出一個紅色豎條,如下圖所示。

分析Flutter應用性能檢測與優化

如果紅色豎條出現在 GPU 線程圖表,意味著渲染的圖形太復雜,導致無法快速渲染;而如果是出現在了 UI 線程圖表,則表示 Dart 代碼消耗了大量資源,需要優化代碼執行時間。

GPU問題定位

GPU渲染問題主要集中在底層渲染耗時上,有時候 Widget 樹雖然構造起來容易,但在 GPU 線程下的渲染卻很耗時。例如,涉及 Widget 裁剪、蒙層這類多視圖疊加渲染,或是由于缺少緩存導致靜態圖像的反復繪制,都會明顯拖慢 GPU 的渲染速度。

接下來,使用性能圖層提供的兩項參數,即檢查多視圖疊加的視圖渲染開關 checkerboardOffscreenLayers和檢查緩存的圖像開關checkerboardRasterCacheImages來檢查這兩種情況。

checkerboardOffscreenLayers

多視圖疊加通常會用到 Canvas 里的 savaLayer 方法,這個方法在實現一些特定的效果(比如半透明)時非常有用,但由于其底層實現會在 GPU 渲染上涉及多圖層的反復繪制,因此會帶來較大的性能問題。

對于 saveLayer 方法使用情況的檢查,我們只需要在 MaterialApp 的初始化方法中,將 checkerboardOffscreenLayers 開關設置為 true,分析工具就會自動幫我們檢測多視圖疊加的情況。使用了 saveLayer 的 Widget 會自動顯示為棋盤格式,并隨著頁面刷新而閃爍。不過,saveLayer 是一個較為底層的繪制方法,因此我們一般不會直接使用它,而是會通過一些功能性 Widget,在涉及需要剪切或半透明蒙層的場景中間接地使用。所以一旦遇到這種情況,我們需要思考一下是否一定要這么做,能不能通過其他方式來實現呢?

比如下面的例子中,我們使用 CupertinoPageScaffold 與 CupertinoNavigationBar 實現了一個動態模糊的效果,代碼如下:

CupertinoPageScaffold(    navigationBar: CupertinoNavigationBar(),//動態模糊導航欄      child: ListView.builder(        itemCount: 100,        //為列表創建100個不同顏色的RowItem        itemBuilder: (context, index)=>TabRowItem(              index: index,              lastItem: index == 100 - 1,              color: colorItems[index],//設置不同的顏色              colorName: colorNameItems[index],            )      )  );

其中,模糊的NavigationBar效果如下圖所示。

分析Flutter應用性能檢測與優化

當我們開啟checkerboardOffscreenLayers之后,可以看到視圖蒙層效果對GPU的渲染壓力導致性能視圖頻繁閃動。如果我們沒有對動態模糊效果有特殊需求,則可以使用不帶模糊效果的 Scaffold 和白色的 AppBar 實現同樣的產品功能,來解決這個性能問題。

Scaffold(    //使用普通的白色AppBar    appBar: AppBar(title: Text('Home', style: TextStyle(color:Colors.black),),backgroundColor: Colors.white),    body: ListView.builder(        itemCount: 100,        //為列表創建100個不同顏色的RowItem        itemBuilder: (context, index)=>TabRowItem(          index: index,          lastItem: index == 100 - 1,          color: colorItems[index],//設置不同的顏色          colorName: colorNameItems[index],        )    ),  );

運行一下代碼,可以看到,在去掉了模糊效果之后,GPU 的渲染壓力得到了緩解,checkerboardOffscreenLayers 檢測圖層也不再頻繁閃爍了。

分析Flutter應用性能檢測與優化

checkerboardRasterCacheImages

從資源的角度看,另一類非常消耗性能的操作是渲染圖像,因為圖像渲染會涉及 I/O、GPU 存儲以及不同通道的數據格式轉換,因此渲染過程的構建需要消耗大量資源。為了緩解 GPU 的壓力,Flutter 提供了多層次的緩存快照,這樣 Widget 重建時就無需重新繪制靜態圖像了。

與檢查多視圖疊加渲染的 checkerboardOffscreenLayers 參數類似,Flutter 提供了檢查緩存圖像的開關 checkerboardRasterCacheImages,來檢測在界面重繪時頻繁閃爍的圖像。

為了提高靜態圖像顯示性能,我們可以把需要靜態緩存的圖像加到 RepaintBoundary 中,RepaintBoundary 可以確定 Widget 樹的重繪邊界,如果圖像足夠復雜,Flutter 引擎會自動將其緩存,從而避免重復刷新。當然,因為緩存資源有限,如果引擎認為圖像不夠復雜,也可能會忽略 RepaintBoundary。下面的代碼展示了通過 RepaintBoundary,將一個靜態復合 Widget 加入緩存的具體用法,如下所示。

RepaintBoundary(//設置靜態緩存圖像    child: Center(      child: Container(        color: Colors.black,        height: 10.0,        width: 10.0,      ),  ));

UI 線程問題定位

如果說 GPU 線程問題定位的是渲染引擎底層渲染異常,那么 UI 線程問題發現的則是應用的性能瓶頸。比如在視圖構建時,在 build 方法中使用了一些復雜的運算,或是在主 Isolate 中進行了同步的 I/O 操作。這些問題,都會明顯增加 CPU 的處理時間,拖慢應用的響應速度。

針對這類問題,我們可以使用 Flutter 提供的 Performance 工具,來記錄應用的執行軌跡。Performance 是一個強大的性能分析工具,能夠以時間軸的方式展示 CPU 的調用棧和執行時間,去檢查代碼中可疑的方法調用。

打開 Android Studio 底部工具欄中的“Open DevTools”按鈕之后,系統會自動打開 Dart DevTools 的網頁,將頂部的 tab 切換到 Performance 后,我們就可以開始分析代碼中的性能問題了。

分析Flutter應用性能檢測與優化

分析Flutter應用性能檢測與優化

接下來,我們通過一個在 ListView 中計算 MD5 的例子來演示 Performance 的具體分析過程。考慮到在 build 函數中進行渲染信息的組裝是一個常見的操作,為了演示Performance的使用過程,我們故意放大計算 MD5 的耗時,如循環迭代計算了 1 萬次。

class MyHomePage extends StatelessWidget {    MyHomePage({Key key}) : super(key: key);    String generateMd5(String data) {      //MD5固定算法      var content = new Utf8Encoder().convert(data);      var digest = md5.convert(content);      return hex.encode(digest.bytes);    }    @override    Widget build(BuildContext context) {      return Scaffold(        appBar: AppBar(title: Text('demo')),        body: ListView.builder(            itemCount: 30,// 列表元素個數            itemBuilder: (context, index) {              //反復迭代計算MD5              String str = '1234567890abcdefghijklmnopqrstuvwxyz';              for(int i = 0;i<10000;i++) {                str = generateMd5(str);              }              return ListTile(title: Text("Index : $index"), subtitle: Text(str));            }// 列表項創建方法        ),      );    }  }

與性能圖層能夠自動記錄應用執行情況不同,使用 Performance 來分析代碼執行軌跡,我們需要手動點擊【Record】按鈕去主動觸發,在完成信息的抽樣采集后再點擊【Stop】按鈕結束錄制,然后就可以得到在這期間應用的執行情況了。

Performance 記錄的應用執行情況叫做 CPU 幀圖,又被稱為火焰圖。火焰圖是基于記錄代碼執行結果所產生的圖片,用來展示 CPU 的調用棧,表示的是 CPU 的繁忙程度。所以,我們要檢測 CPU 耗時問題,皆可以查看火焰圖底部的哪個函數占據的寬度最大。只要有“平頂”,就表示該函數可能存在性能問題,如下圖所示。

分析Flutter應用性能檢測與優化

可以看到,_MyHomePage.generateMd5 函數的執行時間最長,幾乎占滿了整個火焰圖的寬,而這也與代碼中存在的問題是一致的。在找到了問題之后,我們就可以使用 Isolate(或 compute)將這些耗時的操作挪到并發主 Isolate 之外去完成了。

到此,關于“分析Flutter應用性能檢測與優化”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仁寿县| 七台河市| 新晃| 卢湾区| 杭锦后旗| 金山区| 紫阳县| 台前县| 鄯善县| 来安县| 江孜县| 天镇县| 剑河县| 抚顺市| 商洛市| 宁陵县| 晋城| 汶上县| 河北省| 怀集县| 武强县| 剑阁县| 博湖县| 芜湖县| 澄江县| 工布江达县| 柳河县| 顺昌县| 贡觉县| 安多县| 太康县| 平顶山市| 巩义市| 潢川县| 新蔡县| 汝阳县| 桦川县| 黄冈市| 巫山县| 洛南县| 和平县|