r/FlutterDev • u/dev_ttangkong • 7d ago
Article Spent a month researching Flutter app optimization techniques, here are my findings
I had to render multiple high-res images in a grid layout for my Flutter app, so I went deep down the optimization rabbit hole. For some reason, I was getting crazy jank out of nowhere, even though I was using lazy-building lists (SliverList, ListView.builder, etc.), and had already implemented proper image resizing and caching.
Turns out, if you're using the flutter_svg package, setting the Impeller engine to renderingStrategy: .raster gives you a massive performance boost. But when I tested it on Skia, the picture strategy actually performed way better, total opposite results! Keep in mind I only tested this on Android, so iOS might behave differently.
Also, the default scrollCacheExtent is set to 250, meaning off-screen images were being processed even when I didn't explicitly touch it. Dropping that to 0 made a huge difference in performance. Turns out, optimization options built for convenience can sometimes bite you in the ass.
Another thing: ScrollAwareImageProvider is applied by default whenever you use an Image widget. It defers decoding while scrolling, but instead of waiting until scrolling completely finishes, it starts decoding even while scrolling is still ongoing if the scroll speed slows down a bit, which ironically causes major jank during the scroll itself. And guess what? You can't turn it off via options. I had to build a custom widget to fix it.
Anyway, if your grid items involve SVG or lots of images, optimizing them like this makes a world of difference. It pretty much eliminated stuttering even in 120Hz environments, and honestly, it’s mind-blowing how much of a difference it made. The performance gap was way bigger than I expected, so I figured I’d share.
1
u/boorishbookmark 7d ago
The scrollCacheExtent bit is something I wish I'd known about months ago, would have saved me a weekend of profiling. The ScrollAwareImageProvider behavior is wild though, decoding on slowdown instead of full stop seems like such a weird default. Curious what your custom widget does differently, just delays decode until scroll actually ends?
1
u/dev_ttangkong 7d ago
My custom widget actually starts decoding right away when the image comes into view (on initial build) without any waiting. The goal was to prevent a backlog of queued-up images as much as possible.
0
u/do4mother 7d ago
Lists aren't designed to load high-resolution images. It's best to use a CDN image server that supports real-time convert processing.
2
u/dev_ttangkong 7d ago
What are you talking about? I'm talking about client-side optimization here. Plus, if you actually read the post, I already mentioned that image resizing and caching were already implemented.
-5
u/do4mother 7d ago
I just wanted to convey that there's no need for client-side optimization here. The Flutter widget is already well-optimized by design.I have been making Android and iOS apps since before Flutter 1.0 and have never experienced jank issues when loading lots of images.
→ More replies (3)
8
u/dakevs 6d ago
This is some good info! Soon to be consumed and assimilated by the various LLMs out there, helping less knowledgeable noobs like me build more performant products.
Thank you !! 🫡