← 返回首页

Flutter 性能优化:让你的 App 流畅到极致

使用 DevTools 定位卡顿,掌握 Widget 重建优化、图片缓存、Isolate 并发等实用技巧。

使用 DevTools 定位问题

优化的第一步是测量,不要靠猜。Flutter DevTools 提供了完整的性能分析工具:

flutter run --profile  # 以 Profile 模式运行(接近 Release 性能)
# 然后在 VS Code / Android Studio 中打开 DevTools

重点关注 Timeline 面板中的 UI 线程和 GPU 线程。如果某一帧超过 16ms(60fps)或 8ms(120fps),就会出现丢帧卡顿。Widget Rebuild Stats 可以显示每次 setState 后哪些 Widget 发生了重建。

⚠️ 重要

永远不要在 Debug 模式下测量性能,JIT 编译和 Debug 断言会使性能大幅低于实际。始终用 Profile 或 Release 模式测试。

减少不必要的 Widget 重建

这是最高频的性能问题。setState() 会重建调用它的 Widget 及其所有子孙节点,即使大多数子 Widget 的数据并没有变化。

拆分 Widget,缩小重建范围:

// ❌ 错误:整个页面都会重建
class BadPage extends StatefulWidget {
  @override
  State<BadPage> createState() => _BadPageState();
}

class _BadPageState extends State<BadPage> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 这个超重的 Widget 每次都会重建!
        const HeavyStaticWidget(),
        Text('$_count'),
        ElevatedButton(
          onPressed: () => setState(() => _count++),
          child: const Text('+'),
        ),
      ],
    );
  }
}

// ✅ 正确:只让 Counter 部分重建
class GoodPage extends StatelessWidget {
  const GoodPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const HeavyStaticWidget(), // 永远不重建
        const CounterWidget(),     // 只有这部分重建
      ],
    );
  }
}

列表性能优化

永远使用 ListView.builder 而非 ListView,前者是懒加载的,只渲染可见区域的 item:

// ✅ 懒加载,支持百万条数据
ListView.builder(
  itemCount: items.length,
  // 为每个 item 提供固定高度,让 Flutter 跳过高度计算
  itemExtent: 72.0,
  itemBuilder: (context, index) {
    return ItemWidget(item: items[index]);
  },
)

// 对于不定高的复杂列表,用 cacheExtent 预加载屏幕外内容
ListView.builder(
  cacheExtent: 500, // 预加载 500px 高度的内容
  ...
)

图片与内存优化

// 1. 指定图片尺寸,让引擎在解码时就缩放到目标尺寸,而非加载原图
Image.network(
  url,
  width: 200,
  height: 200,
  cacheWidth: 200,   // 内存中缓存的宽度(像素)
  cacheHeight: 200,
)

// 2. 使用 cached_network_image 插件做磁盘缓存
CachedNetworkImage(
  imageUrl: url,
  placeholder: (context, url) => const CircularProgressIndicator(),
  errorWidget: (context, url, error) => const Icon(Icons.error),
)

Isolate 并发计算

Flutter 是单线程的(Dart 主 Isolate),CPU 密集型操作(JSON 解析、图片处理、加密)会阻塞 UI 线程导致卡顿。使用 compute() 将任务放到独立 Isolate:

// 解析大 JSON(在独立 Isolate 中执行,不阻塞 UI)
Future<List<User>> parseUsers(String jsonStr) async {
  return compute(_parseUsersIsolate, jsonStr);
}

// 注意:这个函数必须是顶级函数或静态方法
List<User> _parseUsersIsolate(String jsonStr) {
  final list = jsonDecode(jsonStr) as List;
  return list.map((e) => User.fromJson(e)).toList();
}

const 的力量

加上 const 的 Widget 会在编译期创建,运行时直接复用相同实例,完全跳过重建过程。这是零成本优化:

// ✅ 所有固定 Widget 都加 const
const SizedBox(height: 16)
const Icon(Icons.star)
const Text('固定文字')

性能 Checklist

  • ✅ 静态 Widget 加 const
  • ✅ 列表使用 ListView.builder
  • ✅ 拆分 Widget 树,缩小 setState 影响范围
  • ✅ 图片指定 cacheWidth/cacheHeight
  • ✅ CPU 密集任务放 Isolate
  • ✅ 用 RepaintBoundary 隔离独立绘制区域
  • ✅ 避免在 build() 中做计算(每帧都会执行)
  • ✅ Profile 模式下验证优化效果