一、渲染性能优化
1、减少Widget重建
使用const
构造函数 对静态Widget使用const
,减少重复构建:
scss
const Text('Hello World'), // ✅ 编译时即确定,不会重复创建
Text('Hello World'), // ❌ 每次build都会新建实例
分离动画与子组件 使用AnimatedBuilder
避免动画导致整个子树重建:
less
AnimatedBuilder(
animation: _animation,
builder: (context, child) => Transform.rotate(
angle: _animation.value,
child: child, // ✅ 复用child,不重复构建
),
child: const HeavyWidget(), // 静态子组件
)
2、重绘区域隔离
用RepaintBoundary
包裹频繁重绘的组件(如游戏角色):
less
RepaintBoundary(
child: CustomPaint(painter: MyDynamicPainter()),
)
3、避免在build()中创建对象
scss
// ❌ 错误:每次build都新建
Widget build() {
final logger = Logger();
return ...;
}
// ✅ 正确:提前创建或使用const
static const _logger = Logger();
Widget build() => ...;
4、避免不必要的布局计算
动态高度布局导致重复计算
less
优化前:
Column(
children: [
const HeaderWidget(),
ListView( // ❌ ListView在Column中会引发布局冲突
children: items.map((e) => ItemWidget(e)).toList(),
),
],
)
优化后:
Column(
children: [
const HeaderWidget(),
Expanded( // ✅ 使用Expanded约束ListView高度
child: ListView.builder(
itemCount: items.length,
itemBuilder: (ctx, i) => ItemWidget(items[i]),
),
),
],
)
5、拆分复杂Widget树
复杂页面导致单帧渲染时间过长
scss
优化前:
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
// 100行嵌套布局...
],
),
);
}
优化后:
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
const HeaderSection(), // 拆分为独立组件
const _ContentSection(), // 使用private组件
_buildFooter(), // 提取方法
],
),
);
}
// 拆分成独立的组件或方法
Widget _buildFooter() => ... ;
6、减少Opacity
使用
less
优化前
Opacity(
opacity: 0.5,
child: ComplexWidgetTree(), // ❌ 整个子树都会参与混合计算
)
优化后:
Container(
color: Colors.black.withOpacity(0.5), // ✅ 仅背景透明
child: ComplexWidgetTree(),
)
7、使用ShaderMask
替代复杂遮罩
less
ShaderMask(
blendMode: BlendMode.modulate,
shaderCallback: (Rect bounds) => LinearGradient(
colors: [Colors.red, Colors.blue],
).createShader(bounds),
child: Image.network('...'),
)
8、动画性能优化
使用AnimatedWidget
替代setState
scala
优化前:
AnimationController _controller;
Widget build() {
return Transform.rotate(
angle: _controller.value,
child: Button(
onPressed: () => setState(() {}), // ❌ 触发整个页面重建
),
);
}
优化后:
class _RotatingButton extends AnimatedWidget {
const _RotatingButton({required Animation<double> animation})
: super(listenable: animation);
@override
Widget build(BuildContext context) {
final animation = listenable as Animation<double>;
return Transform.rotate(
angle: animation.value,
child: const Button(),
);
}
}
二、列表性能优化
1、ListView.builder按需构建
长列表必须使用ListView.builder
,避免一次性构建所有子项:
less
ListView.builder(
itemCount: 1000,
itemBuilder: (ctx, i) => ListTile(title: Text('Item $i')),
)
2、保持滚动位置状态
使用AutomaticKeepAliveClientMixin
保持Tab页状态:
scala
class _TabPageState extends State<TabPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true; // ✅ 切换Tab不重新加载
// build方法...
}
3、固定列表项高度
明确设置itemExtent
提升滚动流畅度:
less
ListView.builder(
itemExtent: 80, // 每个列表项高度固定为80
// ...
)
4、使用Sliver
实现高性能复杂列表
less
CustomScrollView(
slivers: [
SliverAppBar(...), // 可折叠的AppBar
SliverPersistentHeader(...), // 固定Header
SliverList(
delegate: SliverChildBuilderDelegate(
(ctx, i) => ListItem(data[i]),
childCount: data.length,
),
),
SliverGrid(...), // 混合网格布局
],
)
三、内存优化
1、图片资源优化
使用cached_network_image
缓存网络图片:
less
CachedNetworkImage(
imageUrl: 'https://example.com/image.jpg',
placeholder: (ctx, url) => CircularProgressIndicator(),
)
加载本地图片时指定尺寸:
arduino
Image.asset(
'assets/large_image.png',
width: 200,
height: 200, // ✅ 避免解码原始大图
)
2、及时释放资源
在dispose()
中释放控制器、监听器
java
late final ScrollController _controller;
@override
void dispose() {
_controller.dispose(); // ✅ 防止内存泄漏
super.dispose();
}
四、启动优化
1、延迟插件初始化
将非必要插件延迟到首帧后加载:
csharp
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
// 首帧渲染后初始化
await Future.delayed(Duration.zero);
await ThirdPartyPlugin.init();
}
2、按需加载插件
csharp
// 首页不使用相机功能,延迟加载
void onProfilePageOpen() async {
final cameraPlugin = await CameraPlugin.load();
// 使用插件...
}
3、Isolate处理耗时任务
使用compute
函数执行密集计算:
java
void _processData() async {
final result = await compute(heavyCalculation, data);
// ...
}
五、状态管理优化
1、局部刷新
Provider中使用Consumer
或Selector
避免全局刷新:
javascript
Selector<AppState, String>(
selector: (_, state) => state.username,
builder: (_, username, __) => Text(username),
)
2、防抖与节流
使用rxdart
控制频繁触发的事件:
scss
searchInput.onTextChanged
.debounceTime(Duration(milliseconds: 500)) // 500ms内只取最后一次
.listen((text) => fetchData(text));
六、工具使用技巧
1、性能Overlay快速诊断
ini
void main() {
debugProfileBuildsEnabled = true; // 启用构建分析
debugProfilePaintsEnabled = true; // 查看重绘区域
runApp(MyApp());
}
2、分步引擎初始化
scss
void main() {
runApp(SplashScreen()); // 极简启动屏
Future.wait([
_warmupEngine(),
_preloadCriticalData(),
]).then((_) => _enterMainApp());
}
Future<void> _warmupEngine() async {
// 后台初始化非必要引擎模块
await Firebase.initializeApp();
await Hive.initFlutter();
}
3、使用 Dart Wasm
预编译
yaml
# pubspec.yaml
flutter:
module:
web:
wasm: true
bash
flutter build web --wasm # 生成WebAssembly版本
4、使用 Impeller
渲染引擎
arduino
flutter run --enable-impeller # 启用下一代渲染引擎