IntermediateFlutter Performance

How do you avoid unnecessary widget rebuilds in Flutter?

Short Answer

Scope state narrowly (so only the widgets that depend on it rebuild), use `const` constructors wherever possible, and split large build methods into smaller widgets so a change in one part doesn't force the whole tree to re-render.

The single biggest cause of unnecessary rebuilds is calling `setState()` (or having a `Provider`/`Riverpod` watcher) high up in a large widget tree, which forces everything below it to rebuild even if only a small piece actually changed visually. The fix is to push state down: extract the part of the UI that actually changes into its own small widget, and keep state management scoped to just that subtree.

For Provider/Riverpod specifically, prefer `Selector`/`Consumer` (or `ref.watch(provider.select(...))` in Riverpod) to listen to only the specific field you need, rather than the whole object. Also use `const` constructors aggressively, and avoid creating new closures or objects inline inside `build()` (e.g. a new `BoxDecoration` every build) since that defeats Flutter's ability to detect "nothing changed."

Common Mistakes

  • ×Wrapping the entire `Scaffold` in a `Consumer`/`Obx` instead of just the small widget that needs the data.
  • ×Creating new callback closures or styling objects inline on every build instead of hoisting them out.