DEV Community

vmodal_ai
vmodal_ai

Posted on

Flutter Performance Optimization: Fix Jank and Dropped Frames

Flutter Performance Optimization: Fix Jank and Dropped Frames

Flutter applications can feel slow even when the underlying device is powerful. Common symptoms include:

  • dropped frames
  • scrolling stutter
  • delayed animations
  • slow startup
  • excessive memory usage
  • expensive rebuilds

This tutorial explains a practical approach to diagnosing and fixing Flutter performance problems.

What is jank?

At approximately 60 FPS:

1000 ms / 60 ≈ 16.67 ms per frame
Enter fullscreen mode Exit fullscreen mode

If a frame takes significantly longer, users may perceive stuttering.

Higher-refresh-rate devices have an even smaller frame budget.

Step 1: Profile before optimizing

Do not optimize based only on intuition.

Use profile mode:

flutter run --profile
Enter fullscreen mode Exit fullscreen mode

Then inspect the application using Flutter DevTools.

Look for:

  • expensive frames
  • rebuilds
  • CPU usage
  • memory allocations
  • image memory
  • network activity

Common problem: rebuilding too much

If a setState() call belongs to a large widget subtree, many widgets may rebuild.

Prefer smaller widget boundaries:

Column(
  children: [
    const ExpensiveHeader(),
    CounterWidget(),
  ],
)
Enter fullscreen mode Exit fullscreen mode

Only the relevant section should rebuild when possible.

Use const constructors

Where appropriate:

const Text('Hello')
Enter fullscreen mode Exit fullscreen mode

Const widgets allow Flutter to reuse immutable widget configurations.

Avoid expensive work in build()

Do not perform expensive operations repeatedly inside build():

Widget build(BuildContext context) {
  final result = expensiveCalculation();
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Prefer caching or calculating the value before the build phase.

List performance

For large lists, use lazy builders:

ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(items[index].title),
    );
  },
)
Enter fullscreen mode Exit fullscreen mode

Avoid constructing thousands of widgets at once.

Image optimization

Large images are a frequent source of memory problems.

If an image is displayed at:

300 x 300
Enter fullscreen mode Exit fullscreen mode

there is little benefit in loading a massive original image unless it is needed elsewhere.

Use appropriate image dimensions and caching.

Expensive visual effects

Effects such as:

Opacity(...)
ClipPath(...)
BackdropFilter(...)
Enter fullscreen mode Exit fullscreen mode

can be expensive depending on the scene.

Do not remove them blindly. Profile complex screens that use many compositing effects.

Animations

Avoid expensive work during animation frames.

Bad:

Animation
  -> API request
  -> JSON parsing
  -> rebuild huge widget tree
Enter fullscreen mode Exit fullscreen mode

Better:

API request
  -> parse data
  -> update state
  -> lightweight animation
Enter fullscreen mode Exit fullscreen mode

Isolate CPU-heavy work

Operations such as:

  • image processing
  • large JSON parsing
  • encryption
  • complex calculations
  • ML preprocessing

may need background execution.

For suitable tasks, Dart isolates can prevent CPU-heavy work from blocking the UI isolate.

Network optimization

A slow application is not always a rendering problem.

Reduce:

  • unnecessary API calls
  • duplicate requests
  • oversized JSON
  • repeated image downloads

Use caching and pagination where appropriate.

Dispose resources

Remember to dispose resources:

@override
void dispose() {
  controller.dispose();
  animationController.dispose();
  super.dispose();
}
Enter fullscreen mode Exit fullscreen mode

Long-lived streams, controllers, and subscriptions can increase memory usage if not released.

Debug vs profile vs release

Do not rely on debug mode for performance conclusions.

Use:

flutter run --profile
Enter fullscreen mode Exit fullscreen mode

for profiling and a release build for production-like testing.

Practical optimization workflow

1. Reproduce the problem
        ↓
2. Profile it
        ↓
3. Identify the bottleneck
        ↓
4. Change one thing
        ↓
5. Profile again
        ↓
6. Compare results
Enter fullscreen mode Exit fullscreen mode

Do not make ten unrelated changes at once.

Performance checklist

  • [ ] Profile important screens
  • [ ] Test scrolling
  • [ ] Test animations
  • [ ] Check image memory
  • [ ] Check network requests
  • [ ] Check startup time
  • [ ] Remove unnecessary rebuilds
  • [ ] Dispose resources
  • [ ] Test on representative devices

Conclusion

Flutter performance optimization is primarily a measurement problem. DevTools can tell you where the time is going; your job is to reduce the work performed during critical UI frames.

Useful Links

SDK Flutter: https://github.com/v-modal/vmodal_sdk_flutter

SDK Android: https://github.com/v-modal/vmodal_sdk_android

Discord: https://discord.gg/K72z28KUx

Top comments (0)