zhaobinglong / myBlog

https://zhaobinglong.github.io/myBlog/
MIT License
7 stars 0 forks source link

Flutter应用性能优化 #73

Open zhaobinglong opened 3 years ago

zhaobinglong commented 3 years ago

长列表懒加载ListView.builder

标准的 ListView 构造函数适用于短列表,对于具有大量列表项的长列表,需要用 ListView.builder 构造函数来创建。与标准的 ListView 构造函数需要一次性创建所有列表项不同的是,ListView.builder 构造函数只在列表项从屏幕外滑入屏幕时才去创建列表项。

demo


// 准备列表数据,这个数据来自后端接口
final items = List<String>.generate(10000, (i) => "Item $i");

// 开始渲染数据,将数据渲染为一个一个的组件
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text('${items[index]}'),
    );
  },
);

参考

https://mp.weixin.qq.com/s?__biz=MzUyMjg5NTI3NQ%3D%3D&chksm=f9c5a837ceb2212161e1486f4fd12d4ebd188e754643dd65868e4bbdddce33cd2e5f475fba35&idx=1&mid=2247484147&scene=21&sn=a980c445b460d09d137c90ff8ff74da0#wechat_redirect

zhaobinglong commented 3 years ago

局部刷新GlobalKey

Flutter中Widget分为StatefulWidget和StatelessWidget,分别为动态视图和静态视图,视图的更新需要调用StatefulWidget的setState方法,这会遍历调用子Widget的build方法。当一个主页面比较复杂时,会包含多个widget,如果直接调用setState,会遍历所有子Widget的build,这是非常不必要的性能开销,有没有单独刷新指定Widget的方式呢?这个时候就要用到GlobalKey了。

参考

https://www.jianshu.com/p/23a2e8a96a79

zhaobinglong commented 3 years ago

耗时计算放到Isolate(多线程)

Flutter应用中的Dart代码执行在UI Runner中,而Dart是单线程的,我们平时使用的异步任务Future都是在这个单线程的Event Queue之中,通过Event Loop来按顺序执行。(这个单线程模型和js是一样的)

也就是说即使我们是异步执行这段计算代码,但由于这段代码耗时过长,那么这段时间内线程没有空闲(可以理解为任务代码都是插空执行?),也就是线程过载了。导致期间Widget的layout等计算迟迟无法执行,那么时间越长,卡顿的现象就越明显。

因此使用Isolate来处理耗时计算,利用多线程来做到代码的并行执行。