Lesson 23 / 25
Performance and DevTools
Smooth frames and fewer rebuilds.
Staying within the frame budget
At 60 Hz each frame has about 16 ms (about 8 ms at 120 Hz) for build, layout and paint. Always measure in profile mode (flutter run --profile) on a real device - debug mode is much slower. DevTools shows frame timings (jank appears as slow UI or raster frames), a CPU profiler, memory usage and a rebuild tracker. Common fixes: use const widgets, split big build methods into smaller widgets so setState rebuilds less, use select/Consumer to narrow rebuilds, build lists lazily, size and cache images, avoid Opacity and clipping in animations where possible, wrap frequently repainting areas in RepaintBoundary, and move heavy work such as parsing large JSON off the UI isolate with Isolate.run or compute.
Heavy parsing off the UI thread
Isolate.run (Dart 2.19+) keeps frames smooth.
import 'dart:convert';
import 'dart:isolate';
Future<List<Todo>> parseTodos(String body) {
// runs the closure on a short-lived background isolate
return Isolate.run(() {
final list = jsonDecode(body) as List<dynamic>;
return list
.map((e) => Todo.fromJson(e as Map<String, dynamic>))
.toList();
});
}
// Profile on a device:
// flutter run --profile
// then open DevTools from the link printed in the terminal.Rebuilds are cheap, layout and paint less so
Do not obsess over every rebuild. Profile first; the expensive problems are usually large images, unbounded lists, heavy work in build and repaints during animation.
Quick check: Which build mode should you use to measure performance?
- Profile mode on a real device
- Debug mode on an emulator
- Hot reload
- Release mode with DevTools disabled always
Answer
Profile mode on a real device — Debug mode adds assertions and JIT overhead; profile mode is close to release but still supports DevTools.