The Magic of Repaint Boundary!
What is a RepaintBoundary?
A RepaintBoundary is like a boundary or fence for a widget and its children. It separates their rendering process into its own layer. This means when something inside the boundary changes, only that part gets repainted instead of the entire surrounding UI.
Basically, it helps avoid unnecessary redrawing of larger parts of the screen when only a small change occurs.
For a quick visual overview of RepaintBoundary, check out this 2-minute video to get started.
https://www.youtube.com/embed/cVAGLDuc2xE?si=44qgEKhmExZnnDSH
💡 A Pro Tip:- debugRepaintRainbowEnabled flag
A debugging flag to help visually monitor render tree repaints in a running app.
Overlay a rotating set of colours when repainting layers in debug mode.
void main() {
debugRepaintRainbowEnabled=true;
runApp(const MyApp());
}
Let’s check the behaviour of the RepaintBoundary with a Example
SingleChildScrollView(
child: Column(
children: [
for (int i = 0; i < 50; i++)
Column(
children: [
Card(
elevation: 4,
margin: const EdgeInsets.all(16),
child: Container(
width: 200,
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircleAvatar(
radius: 40,
backgroundColor: Colors.grey[300],
child: Icon(Icons.person,
size: 40,
color: Colors.grey[700]
),
),
const SizedBox(height: 16),
Text('John Doe $i'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => setState(() => isLoading = !isLoading),
child: Text(
isLoading ?
'Stop Loading' :
'Start Loading'),
),
],
),
),
),
if (isLoading)
// Animation affecting the entire tree
CircularProgressIndicator(),
],
),
],
),
);
Behaviour without RepaintBoundary

- Widget Redrawing:
— Whenever the state of the widget (e.g., isLoading
) changes, Flutter has to repaint the entire widget tree.. Even if only one widget CircularProgressIndicator
changes, the lack of a RepaintBoundary
means all widgets in the tree are redrawn unnecessarily.
2. Performance Impact:
— Repainting 50 cards is computationally expensive. This can result in:
- Frame drops.
- Noticeable lag, especially on devices with less processing power.
Now, lets Isolate the loader (CircularProgressIndicator
) with a RepaintBoundary
:
if (isLoading)
RepaintBoundary(
child: CircularProgressIndicator(),// Isolated animation
),
Behaviour with RepaintBoundary

- Widget Isolation:
— By wrapping each CircularProgressIndicator
inside a RepaintBoundary
, Flutter isolates the widget's repainting scope. This means:
- Only the part of the widget tree inside the
RepaintBoundary
is repainted. - Other parts of the widget tree, such as cards that haven’t changed, remain untouched.
2. Performance Improvement:
— With RepaintBoundary
, Flutter optimizes rendering by caching the static parts of the UI and reusing them instead of redrawing everything. This leads to:
- Smoother animations.
- Reduced computational overhead.
- Better frame rates and user experience.
Repaint Boundary Metrics
The metrics provided by the render object linked to a
RepaintBoundary
helps to evaluate its efficiency and determine whether the boundary optimizes performance effectively

Can we use RepaintBoundary everywhere?
While RepaintBoundary can improve performance by caching its contents, overuse increases memory consumption without guaranteed benefits. Excessive boundaries may unnecessarily bloat memory usage without noticeably improving rendering efficiency. Use them selectively in areas with frequent updates or high repaint costs for optimal results.
As per flutter docs :- “Checking for non-cached images”
Caching an image with
RepaintBoundary
is good, when it makes sense.One of the most expensive operations, from a resource perspective, is rendering a texture using an image file. First, the compressed image is fetched from persistent storage. The image is decompressed into host memory (GPU memory), and transferred to device memory (RAM).
In other words, image I/O can be expensive. The cache provides snapshots of complex hierarchies so they are easier to render in subsequent frames. Because raster cache entries are expensive to construct and take up loads of GPU memory, cache images only where absolutely necessary.
How widgets are rendered as UI?
To understand how widgets are rendered as a UI, you can refer to the Flutter documentation on Flutter’s rendering model.
We’ll dive deeper into this topic in a future article!
Summary
- Use
RepaintBoundary
strategically to isolate widgets with frequent updates or animations from the rest of the UI! RepaintBoundary
ensures that the animation's effect is localized, improving performance and keeping the UI responsive
References
