Flutter 性能优化
渲染性能
减少 Widget 重建
dart
// ❌ 避免:整个列表重建
class BadList extends StatelessWidget {
final List<Item> items;
@override
Widget build(BuildContext context) {
return ListView(
children: items.map((item) => ItemWidget(item)).toList(),
);
}
}
// ✅ 推荐:使用 builder 按需创建
class GoodList extends StatelessWidget {
final List<Item> items;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) => ItemWidget(items[index]),
);
}
}使用 const 构造函数
dart
// ✅ 使用 const,避免重建
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: const [
Text('Static Text'), // 不会重建
Icon(Icons.star), // 不会重建
],
);
}
}RepaintBoundary
dart
// 隔离重绘区域
CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: RepaintBoundary(
child: ExpensiveWidget(), // 独立重绘
),
),
// 其他 slivers...
],
)列表性能
大列表优化
dart
// 使用 ListView.builder 虚拟化
ListView.builder(
itemCount: 10000,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
)
// 使用 itemExtent 提升性能(固定高度)
ListView.builder(
itemCount: 10000,
itemExtent: 60.0, // 固定高度
itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
)图片列表优化
dart
ListView.builder(
itemBuilder: (context, index) {
return Image.network(
urls[index],
// 限制缓存大小
cacheWidth: 200,
cacheHeight: 200,
// 使用占位符
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
if (wasSynchronouslyLoaded) return child;
return AnimatedOpacity(
opacity: frame == null ? 0 : 1,
duration: Duration(milliseconds: 300),
child: child,
);
},
);
},
)动画性能
使用 AnimatedBuilder
dart
// ❌ 避免:整个 Widget 重建
class BadAnimation extends StatefulWidget {
@override
State<BadAnimation> createState() => _BadAnimationState();
}
class _BadAnimationState extends State<BadAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
Widget build(BuildContext context) {
// 整个树重建
return Transform.rotate(
angle: _controller.value * 2 * pi,
child: ExpensiveWidget(),
);
}
}
// ✅ 推荐:只重建动画部分
class GoodAnimation extends StatefulWidget {
@override
State<GoodAnimation> createState() => _GoodAnimationState();
}
class _GoodAnimationState extends State<GoodAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform.rotate(
angle: _controller.value * 2 * pi,
child: child, // child 不重建
);
},
child: ExpensiveWidget(), // 只创建一次
);
}
}内存优化
图片内存管理
dart
// 限制图片缓存
PaintingBinding.instance.imageCache.maximumSize = 100;
PaintingBinding.instance.imageCache.maximumSizeBytes = 50 << 20; // 50MB
// 清理缓存
PaintingBinding.instance.imageCache.clear();避免内存泄漏
dart
class MyWidget extends StatefulWidget {
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late StreamSubscription _subscription;
late AnimationController _controller;
@override
void initState() {
super.initState();
_subscription = stream.listen((_) {});
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
// ✅ 必须释放资源
_subscription.cancel();
_controller.dispose();
super.dispose();
}
}启动优化
减少启动时加载
dart
// 延迟初始化
late final heavyObject = HeavyClass();
// 异步初始化
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// 并行初始化
await Future.wait([
SharedPreferences.getInstance(),
Firebase.initializeApp(),
]);
runApp(MyApp());
}预编译 Shader
bash
# 收集 shader
flutter run --profile --cache-sksl
# 使用 shader 构建
flutter build apk --bundle-sksl-path=flutter_01.sksl.json性能分析工具
dart
// 开启性能统计
import 'dart:developer' as developer;
void measurePerformance() {
developer.Timeline.startSync('MyOperation');
// 执行操作
developer.Timeline.finishSync();
}
// 使用 DevTools
// flutter run --profile
// 打开 DevTools 的 Performance 面板面试要点
- Widget 重建优化:const、builder、RepaintBoundary
- 列表优化:虚拟化、固定高度、图片缓存
- 动画优化:AnimatedBuilder 隔离重建
- 内存管理:dispose 释放资源、图片缓存控制