Optimize Flutter Performance: Handle Heavy Image with Ease
SR
Sabin Ranabhat
February 22, 2024•4 min read

Recently, I came across a property in Flutter: debugInvertOversizedImages.
You might think, "What does it do?" Okay, let me answer you.
This property takes a boolean value, i.e., true or false; by default, it is false. If we make it true, then it will invert color and flip the images that are larger than their display size. With the help of this property, developers can easily stop oversized images on their app.
How do I enable the debugInvertOversizedImages property?
Go to your main.dart file. Inside the main method, add this line:
debugInvertOversizedImages = true;
I have added a high-resolution image to my assets, and below is my demo implementation.
Image.asset('assets/demo.jpg')
Now run your app. You can see all the oversized images being color-inverted and flipped by Flutter.
And if you check your logs, then you might see something like this:
EXCEPTION CAUGHT BY PAINTING LIBRARY
The following message was thrown while painting an image:
Image assets/demo. jpg has a display size of 1080×1439 but a decode size of 3688*4917, which uses an additional 86347KB (assuming a device pixel ratio of 2.625).
Consider resizing the asset ahead of time, supplying a cacheWidth parameter of 1080, a cacheHeight parameter of 1439, or using a ResizeImage.
Here, we are trying to load an image of 3688×4917, but actually, the display size is 1080×1493. And on the second line, we can see the solutions too.
Let’s try the first solution by adding the `cacheHeight` and `cacheWidth` parameters to the `Image` widget with the recommended dimensions provided by Flutter on the console.
```dart
Image.asset(
'assets/demo.jpg',
cacheHeight: 1439,
cacheWidth: 1080,
)
Voilà, now your image will be displayed perfectly fine.
Now, let’s try with ResizeImage
Before that, let's learn what ResizeImage is.
Flutter’s ResizeImage class allows you to specify the desired dimensions at which images are decoded and cached instead of their full dimensions without altering the original image file. By resizing images to appropriate dimensions, we can significantly reduce memory usage and improve image loading time.
Now replace Image.asset with AssetImage, as ResizeImage takes image providers only. And set width and height to the same values we have added previously. We cannot display ResizeImage directly, so let’s wrap it in the Image widget.
Image(
image: ResizeImage(
AssetImage('assets/demo.jpg'),
height: 1439,
width: 1080,
),
)
If both do the same thing, then what’s the difference? You might be wondering.
The cacheWidth and cacheHeight parameters of Image.asset are used for static resizing images before loading into the UI and remain the same for the whole lifetime of the app. The ResizeImage class is used for dynamic resizing of images at runtime and is generated every time the ImageProvider is used.
If you ask for my recommendation, I recommend you use the former one. Yes, cacheWidth and cacheHeight parameters of the Image widget. This can be used on Image.asset, Image.network, Image.file, and Image.memory.
What if you are using the cache_networked_image package instead of Image.network?
You can pass your desired dimension value to the memCacheHeight and memCacheWidth properties of the CachedNetworkImage class. If you are using the CachedNetworkImageProvider class, then you don’t have access to these properties. Instead, you should wrap it under ResizeImage.
Bonus: Dynamically determining image cache size by Extensions and MediaQuery class
The usage of ImageExtension is pretty simple.
extension ImageExtension on num {
int cacheSize(BuildContext context) {
return (this * MediaQuery.of(context).devicePixelRatio).round();
}
}
// Usage
Image.asset(
'assets/demo.jpg',
cacheHeight: 550.cacheSize(context),
cacheWidth: 410.cacheSize(context),
)
Conclusion
In this article, we explored how to load heavy images efficiently and optimize performance when displaying heavy images from assets and networks.
Links
Share this article:
Related Posts

Blog
February 4, 2024
Exploring Parallelism on Flutter: Main Thread, Isolate and Compute
Understanding the nuances of main thread, isolates, and compute empowers you to make informed decisions about concurrency in your Flutter projects.

Blog
February 12, 2024
Concurrent Asynchronous Operations in Dart: A Guide to Future.wait
Introduction: Dart has provided a method “Future.wait” that provides an efficient way to handle multiple asynchronous operations concurrently.
© 2025 Sabin Ranabhat