Sitemap
Ramadan Sayed

Ramadan Sayed

Software engineer, 9 years in. I write about the parts of software nobody documents — and whatever else I can't stop thinking about.

Member-only story

Compose Performance Part 7: Images at Scale with Coil 3 — Why AsyncImage Is More Expensive Than You Think, Bitmap Memory Math (Width × Height × 4 Bytes), Proper Image Sizing Before Bitmap Decode, Memory Cache vs Disk Cache Configuration, Crossfade Performance Costs, Placeholder Strategies, Sub-Sampling for Large Images, Pre-Caching Strategies, Coil 3 Multiplatform Configuration, and the Patterns That Make Image-Heavy Lists Scroll as Smoothly as Text-Only Ones

12 min readAug 1, 2026

You did everything right in Part 6. Your LazyColumn has keys, contentType, stable items, deferred animation reads, the works. Your list scrolls smoothly with text-only items. Then you add AsyncImage to each row, and suddenly the list stutters every time the user scrolls. Frame drops appear during fling. Memory usage climbs. On lower-end devices, the list becomes unusable.

Images are where many Android apps quietly leak performance. The framework makes loading images look easy — AsyncImage(model = url, contentDescription = null) and you're done — but that simplicity hides a series of performance landmines: bitmap memory cost, cache misses, decode-on-main-thread, oversized bitmaps for tiny views, crossfade animations during scroll, and placeholder thrashing. Get them wrong and the smoothest LazyColumn in the world feels janky.

--

--

Ramadan Sayed
Ramadan Sayed

Written by Ramadan Sayed

Software engineer, 9 years in. I write about the parts of software nobody documents — and whatever else I can't stop thinking about.