【发布时间】:2021-07-25 06:00:29
【问题描述】:
下面是一个展示我关心的最小应用程序。如果你运行它,你会看到每个可见项目的 build 方法都会运行,即使只有一个项目的数据发生了变化。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyList extends StatelessWidget {
final List<int> items;
MyList(this.items);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
print("item $index built");
return ListTile(
title: Text('${items[index]}'),
);
});
}
}
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<int> items = List<int>.generate(10000, (i) => i);
void _incrementItem2() {
setState(() {
this.items[1]++;
});
}
@override
Widget build(BuildContext context) {
final title = 'Long List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Column(
children: <Widget>[
MyButton(_incrementItem2),
Expanded(child: MyList(this.items))
],
),
),
);
}
}
class MyButton extends StatelessWidget {
final Function incrementItem2;
void handlePress() {
incrementItem2();
}
MyButton(this.incrementItem2);
@override
Widget build(BuildContext context) {
return TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(Colors.blue),
),
onPressed: handlePress,
child: Text('increment item 2'),
);
}
}
在 React / React Native 中,我会使用 shouldComponentUpdate 或 UseMemo 来防止不必要的渲染。我想在 Flutter 中做同样的事情。
这是 Flutter github 上关于同一主题的已关闭问题的链接: (我将在那里评论这个问题的链接) https://github.com/flutter/flutter/issues/19421
在 Flutter 中避免无用的“重新渲染”或调用 build 方法的最佳实践是什么,或者考虑到 Flutter 和 React 之间的结构差异,这些额外的构建是否不是一个严重的问题?
这或多或少类似于几年前在堆栈溢出时提出的这个问题:How to Prevent rerender of a widget based on custom logic in flutter?
一个赞成的答案是使用 ListView.builder。虽然这可以阻止一些即使不是大多数无用的渲染,但它并不能阻止所有无用的渲染,如我的示例所示。
提前感谢您的知识和洞察力。
【问题讨论】:
-
使用提供者或集团
-
检查
ValueListenableBuilder文档(并参见 youtube.com/watch?v=s-ZG-jS5QHQ&t=6s)但老实说,我认为您对性能问题有点夸大了 -
是的,到目前为止还没有遇到性能问题,但没有过分担心,@pskink,考虑到我考虑从 React Native 切换到 Flutter 的主要原因是性能。
-
ok 多少次(例如每秒)
MyList重建?另外,ListView.builder中有多少可见项目? -
MyList 的可见项(其中大约 14 个)只会在每次更改数据时重建一次。在 React Native 中,鉴于 js 桥,这是一个问题。很高兴确认这在 Flutter 中不是一个问题。
标签: flutter