Nguyên nhân thường gặp: ảnh được giải mã ở kích thước gốc. Ảnh trong bộ nhớ ở dạng chưa nén, khoảng width × height × 4 byte — ảnh 4K (3840×2160) chiếm hơn 30 MB RAM dù chỉ hiển thị thành thumbnail 120×120. Vài chục ảnh như vậy trong một feed là đủ khiến app bị kill.
Cách xử lý theo thứ tự hiệu quả:
1. Tải đúng kích thước từ server/CDN — API trả URL thumbnail thay vì ảnh gốc.
2. Giải mã đúng kích thước hiển thị bằng cacheWidth/cacheHeight (đơn vị pixel vật lý):
final dpr = MediaQuery.devicePixelRatioOf(context);
Image.network(
item.imageUrl,
width: 120,
height: 120,
cacheWidth: (120 * dpr).round(), // decode at display size, not original
fit: BoxFit.cover,
)3. Danh sách lazy: ListView.builder/GridView.builder chỉ build item đang hiển thị.
4. Cache trên đĩa cho ảnh mạng (cached_network_image) để cuộn lại không tải lại.
Tìm ảnh quá khổ bằng DevTools → Inspector → Highlight oversized images: ảnh giải mã lớn hơn cần thiết sẽ bị đảo màu và lật ngược.
Nền tảng khác cùng nguyên lý: Android dùng Coil/Glide (tự downsample theo kích thước view), React Native dùng expo-image hoặc FastImage.
Lưu ý: ImageCache giữ ảnh đã giải mã trong RAM sau khi rời màn hình; nếu app chủ yếu hiển thị ảnh lớn, có thể giảm PaintingBinding.instance.imageCache.maximumSizeBytes.