flutter on a 2GB android phone: what actually made our app usable
not the stuff from the conference talk, the stuff that moved the numbers on real cheap phones
Contents
so we build a delivery and payments app for a client here in lagos and most of their users are on phones with 2 or 3GB ram, android 9 to 11, storage almost full because of whatsapp media. our app was "smooth" on the dev team phones and absolute garbage on the real ones. here is what moved the needle for us, roughly in order of how much it helped
1. stop judging performance in debug mode
sounds obvious but half the team was judging speed with flutter run in debug. debug mode is JIT and has asserts on, it will always feel slow. use flutter run --profile on a real cheap device and open devtools. if you dont own a cheap device buy one, its the best money you will spend this year
2. decode images at the size you show them
this one was the biggest win for memory. a product photo from the backend was 2000px wide and we showed it in a 120px thumbnail, and flutter was decoding the full thing into memory. multiply by a list of 50 items and android kills the app in the background. use cacheWidth / cacheHeight on Image.network (or memCacheWidth if you use cached_network_image) so it decodes small. better still, ask the backend for a thumbnail size
Image.network(
product.imageUrl,
width: 120,
cacheWidth: (120 * MediaQuery.of(context).devicePixelRatio).round(),
)
3. ListView.builder for anything that can grow
we had a screen using ListView(children: [...]) with every order built upfront. builder only builds whats on screen. same for GridView.builder
4. rebuild less
- const constructors everywhere you can, the linter will tell you where
- split big build methods into small widgets so one setState doesnt rebuild the whole screen
- with provider or riverpod use select, so a widget only rebuilds when the field it uses changes, not the whole object
turn on the rebuild stats in devtools and you will be shocked how much rebuilds when you type one letter in a search box
5. animations
dont animate the Opacity widget in a loop, its expensive. use FadeTransition or AnimatedOpacity. wrap things that animate all the time (like a loading shimmer) in a RepaintBoundary so they dont repaint the whole screen with them
6. app size matters more than you think
when storage is almost full people delete the biggest app first. ship app bundles so the store gives each phone only its own ABI (or --split-per-abi for apks), and build with --obfuscate --split-debug-info. our download went from a 38MB universal apk to about 14MB
none of this is magic. the real lesson is just: test on the phone your users actually have. abeg buy the cheap phone
Written by
Tunde Adebayo
Mobile dev (Flutter + React Native) at an agency in Lagos. building fintech and logistics apps mostly. if your app is slow on a 2GB android phone, its not "fine". football on weekends
Get the best of #thumb_zone weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment