Flutter优化我们可以从以下几方面入手

检测工具 Flutter Inspector (debug模式下)

Flutter inspector 页面

点击左上角的图标,进入select widget model 模式,此时点击相应的widget,就可在页面上显示其具体的布局区域


select widget model
  • Highlight Repaints - 上图右上角操作图标的倒数第二个,若是widget发生重绘,就会改变颜色,据此发现频繁重绘的区域


    Highlight Repaints
  • Highlight Oversizeded Images 上图的右上角倒数第一个,该功能会检测出页面中图片实际大小大于显示大小的视图,并将图片进行倒置,便于发现,如何优化下边下边再讲


    Highlight Oversizeded Images
Flutter支持Release、Profile、Debug编译模式。
  1. Release模式,使用AOT预编译模式,预编译为机器码,通过编译生成对应架构的代码,在用户设备上直接运行对应的机器码,运行速度快,执行性能好;此模式关闭了所有调试工具,只支持真机。
  2. Profile模式,和Release模式类似,使用AOT预编译模式,此模式最重要的作用是可以用DevTools来检测应用的性能,做性能调试分析。
  3. Debug模式,使用JIT(Just in time)即时编译技术,支持常用的开发调试功能hot reload,在开发调试时使用,包括支持的调试信息、服务扩展、Observatory、DevTools等调试工具,支持模拟器和真机。

开启profile模式 VSCode launch.json中添加"flutterMode": "profile"

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: 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

如上图所示 蓝色表示 正常帧,绿色表示当前帧,红色表示出现卡顿的帧,结合当前页面和操作 定位卡顿位置

CPU Profiler

定位耗时操作
首先要运行在 profile 模式下
打开Flutter DevTools
搜索栏输入>devtools,点击 Dart: DevTools,并选择浏览器打开


截屏2024-03-21 09.23.23.png

点击record,就开始收集,之后点击stop


截屏2024-03-21 09.26.55.png

横向表示执行时间
竖向表示 调用堆栈
由此分析耗时的方法

对于低端机型的耗时操作 可开启新的线程处理


截屏2024-03-21 09.28.57.png

优化

布局优化

Flutter UI涉及到三棵树

  • widget Tree 配置控件信息,不涉及渲染,更新代价低
  • elememt Tree widget和renderObject的粘合剂
  • RenderObject 真正负责渲染的树,更新代价大

1、build() 不在build中执行耗时操作,由于该方法调用的几率极大,早期开发更新 都是通过调用build进行的,可将耗时操作使用isolate实现
2、尽量将build中的widget的粒度拆小,可复用的模块抽离,拆小力度后可使用 inherteWidget、GetX等按需更新,也增加了 代码的可读性
3,尽量使用const构造器,特别是 一些通用的不更改的常量组件,比如空视图,比如加载中
4、listview构造的时候 尽量使用其 builder构造器,尽量不使用children显示视图,builder是只渲染 显示的部分

内存优化

1、const实例化,const会创建一个编译时的常量,存在一个特殊的查询列表里,仅分配一次内存
2、检测内存消耗过高的图标,上边所示的Highlight Oversizeded Images即可检测,针对大内存的图片 可自行展示大小,长列表大内存图片 可导致app崩溃,也可建立检测机制,检测列表图片的大小 过高的话 上报大数据,具体分析优化


截屏2024-03-21 09.46.05.png

3、listview中有大量image的情况
listview为了保证滑动的性能 会让子widget保持活动状态,这一点事通过AutomaticKeepAlive控制的,再次 向后滑动,为防止widget重新绘制,这个是由RepaintBoundaries 保证的,但是若是加载大量的图片,就会消耗大量的内存,最终可能会导致App崩溃


截屏2024-03-21 09.55.10.png

两个属性都设置为 false后,不可见的子widget就会被 自动处理

4、降低customScrollView listView的预渲染合理值
默认情况下 customscrollview除了渲染 屏幕显示内容外 还会渲染 上下各250区域的内容,可根据每一个item的大小和是否是低端机调整预渲染区域的大小


截屏2024-03-21 09.59.33.png
综合逻辑优化

1、减少自定义的 微任务内容,一般我们认为 微任务多数是系统触发的,但是我们也可以创建 比如Future.value,比如Future(() => null).then(() {})then中的任务就是微任务,以保证future执行完后立刻执行then中的处理,再比如stream任务,也可以自己创建微任务 schedmicroTask,由于微任务的执行优先级 高于UI任务,过多的微任务,会占用cpu,使UI处理滞后,造成卡顿
避免以上情况 就需要按需使用 不显示的页面相应的数据传输就停掉
2、尽可能的小粒度刷新,尽量不使用setstate刷新整个页面,将builder中的视图分成若干widget,按需刷新 可使用inheritWidget或是GetX

内存移除的检测

底层widget 一般是tabbarPage混入 WidgetsBindingObserver,
我们一般是使用这个类来检测app的生命周期 包括 后台 前台 随时可能退出,杀掉进程的状态 但是却忽略了 这里的一个检测 就是检测内存溢出的方法

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

类似于IOS中 viewController中的检测内存溢出的回调方法- (void)didReceiveMemoryWarning,
我们可以在上述方法中进行内存的手动释放

/// 释放图片组件的缓存
DefaultCacheManager().emptyCache();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容