Flutter性能优化实践 —— UI篇,头条android面试节奏

本文探讨了Flutter应用的性能优化,重点关注UI流畅性和GPU效率。建议使用动态构建Widget以减少内存波动,通过错峰加载避免滑动时的卡顿现象。在耗时计算上,避免在UI线程执行,可利用Isolate进行异步处理。对于GPU优化,应减少使用导致离屏渲染的方法,并避免复杂Path操作。文章提供了Flutter性能监控和分析的工具和方法,帮助开发者更好地理解和改进应用性能。
摘要由CSDN通过智能技术生成

推荐使用ListView.builder来动态实现列表,而不是直接使用ListView静态创建。注意这里在使用ListView.builderitemBuilder来构建item时,可不要预构建Widget了。类似的Widget还有PageView.builderGridView.builder

PS:按需加载是一种策略,并不是仅仅依靠这几个类型的Widget。比如之前阿里AliFlutter的分享中,就有提到列表中加载图片的优化。通过判断图片的在屏和离屏,来合理回收图片,这样减小了内存的波动,同样也可以带来性能的提升。

错峰加载

错峰加载的目的是为了避免因同一时间的大量构建,而产生卡顿现象。这里我举一个例子:

在使用PageView.builder这个Widget时,我发现在左右滑动切换页面时会有卡顿的现象。使用timeline来分析发现两个问题,一是切换的页面比较复杂,比较耗时。二是页面构建的时间点在滑动中。

页面复杂的问题我进行了一定的优化,虽然有效果,但还是有卡顿发生。那么只能针对第二点再进行优化,我们先看一下PageView.相关源码:

return NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification.depth == 0 && widget.onPageChanged != null && notification is ScrollUpdateNotification) {
final PageMetrics metrics = notification.metrics;
final int currentPage = metrics.page.round();
if (currentPage != _lastReportedPage) {
_lastReportedPage = currentPage;
widget.onPageChanged(currentPage);
}
}
return false;
},
child: Scrollable(),
);

代码很简单,如果我们设置了onPageChanged的监听,那么在滑动中(ScrollUpdateNotification)计算当前页的页码并返回(round方法,四舍五入)。所以在滑动到一半的时候,onPageChanged就会回调结果,我因为在这里触发了页面的刷新代码,导致了卡顿的发生。

其实在我熟知的安卓中,默认行为都是在滑动结束后才去加载页面数据。所以按照这个思路处理,调整一下加载策略。

修改代码如下:

NotificationListener(
onNotification: (ScrollNotification notification) {
if (notification.depth == 0 && notification is ScrollEndNotification) {
final PageMetrics metrics = notification.metrics;
final int currentPage = metrics.page.round();
if (currentPage != _lastReportedPage) {
_lastReportedPage = currentPage;
_onPageChange(currentPage);
}
}
return false;
},
child: PageView.builder(),
)

我们在PageView.builder上添加一个NotificationListener,同时修改ScrollUpdateNotificationScrollEndNotification。这样就自定义了我们的滑动监听事件,通过错峰加载保证了UI的流畅。

PS:在Flutter 1.17的重要改动中就有一条:[在高速滚动时推迟图像解码](()。这也是运用了错峰加载的策略。

5.耗时计算

避免将一些耗时计算放在UI线程,我们可以把耗时计算放到Isolate去执行(多线程)。

举一个Flutter源码中的例子:

Future loadString(String key, { bool cache = true }) async {
final ByteData data = await load(key);
if (data == null)
throw FlutterError(‘Unable to load asset: k e y ′ ) ; i f ( d a t a . l e n g t h I n B y t e s < 10 ∗ 1024 ) / / 10 K B t a k e s a b o u t 3 m s t o p a r s e o n a P i x e l 2 X L . / / S e e : h t t p s : / / g i t h u b . c o m / d a r t − l a n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值