Flutter : How to Debug which widgets re-rendered on state change Flutter : How to Debug which widgets re-rendered on state change dart dart

Flutter : How to Debug which widgets re-rendered on state change


In flutter, whenever one widget update ; the whole widget tree repaint. So... no.

But you can also introduce "repaint boundaries" manually by inserting in your tree a RepaintBoundary widget. This explicitly tells flutter to create a new painting layer for it's child (which implies memory cache). So that whenever that child updates, it won't repaint it's parent too.

What you can do is instead debug when a repaintboundary is repainted.

For this you can enable repaint rainbow by :

  • pressing t when using flutter run
  • using vscode Dart Code extension with a ctrl/cmd + shift + p and enable repaint rainbow


One thing to note first about rendering: rebuilding and repainting are not the same. Rebuilding involves layout and painting, whereas repainting doesn't involve relayout.

How to check for rebuild

Add a print statement in any build methods that you are interested in.

class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    print('MyApp building');                 <-- this    return MaterialApp(...

And this:

class MyWidget extends StatelessWidget {  const MyWidget({Key key}) : super(key: key);  @override  Widget build(BuildContext context) {    print('MyWidget building');  //         <-- here     return ProgressBar(...

If you notice that there are unnecessary parts of your widget tree getting rebuilt, then the solution is to extract out the parts of the tree that are changing into their own widgets, preferably const widgets.

How to check for repainting

To see what is getting repainted, you can use the Dart DevTools. While you app is running, click the Repaint Rainbow button.

enter image description here

Alternatively, you can use the following flag in your code:

void main() {  debugRepaintRainbowEnabled = true;  //   <-- set this flag to true  runApp(MyApp());} 

The regions that are being repainted have a rainbow border that changes colors on each repaint. As you can see in the animation below, the entire window is getting repainted every time. (The blue line in the center is part of the widget, not the repaint rainbow.)

enter image description here

If you want to limit what is getting painted, you can add a RepaintBoundary widget to your tree like this:

class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    print('MyApp building');    return MaterialApp(      home: Scaffold(        body: Center(          child: Container(            child: RepaintBoundary(  //   <-- repaint boundary              child: ProgressBar(                barColor: Colors.blue,                thumbColor: Colors.red,                thumbSize: 20.0,              ),            ),          ),        ),      ),    );  }}

Now when you use DevTools and select the Repaint Rainbow button, you'll see that only the ProgressBar widget is getting repainted.

enter image description here

If the repaint is not expensive, then this is probably not something you need to worry about. At least in most of the documentation that I've seen, people say to minimize rebuilds, but hardly anyone suggests adding repaint boundaries. I'd check the timeline and performance in DartDev tools to see if you need it. Check out the linked video below for details.

See also:


The best way to debug your application to see what widgets is re-rendered is by inserting break points in your code. I would recommend putting a breakpoint within the Widget build(BuildContext context) method.

Alternatively you could also use print statements to make sure the build method is being called.