CachedNetworkImage es un widget de Flutter para cargar y almacenar en caché imágenes de red con soporte para indicadores de progreso, placeholders y manejo de errores. Según la página oficial del paquete, la biblioteca se basa en flutter_cache_manager y proporciona almacenamiento en caché automático en disco con TTL configurable. CachedNetworkImage es la solución estándar para cargar imágenes en aplicaciones Flutter con almacenamiento en caché.
Puntos clave
CachedNetworkImage es un widget de Flutter del paquete homónimo en pub.dev que proporciona carga de imágenes de red con almacenamiento en caché automático. Es una envoltura sobre el Image.network estándar, añadiendo almacenamiento en caché de archivos, indicadores de progreso y manejo personalizado de errores.
Internamente, CachedNetworkImage utiliza flutter_cache_manager — un gestor de caché con una base de datos SQLite para rastrear archivos. En la primera solicitud, la imagen se descarga de la red, se guarda en el disco, y en solicitudes posteriores se sirve desde la caché teniendo en cuenta el TTL (por defecto 7 días). El almacenamiento en caché en memoria es gestionado por el ImageCache estándar de Flutter.
El paquete cuenta con más de 4,000 me gusta en pub.dev y se utiliza en miles de proyectos Flutter. CachedNetworkImage admite todas las plataformas de Flutter: Android, iOS, Web, macOS, Windows y Linux. Gracias a una API unificada, los desarrolladores obtienen carga de imágenes multiplataforma sin código específico de plataforma.
Flutter utiliza un sistema de almacenamiento en caché de dos niveles: ImageCache (memoria) y flutter_cache_manager (disco + SQLite). ImageCache es un caché global de imágenes decodificadas con límites de cantidad (por defecto 1000) y tamaño (por defecto 100 MB). flutter_cache_manager gestiona los archivos en disco y sus metadatos.
Cuando CachedNetworkImage recibe una solicitud de imagen, primero verifica el ImageCache de Flutter — si la imagen ya está decodificada en memoria, se muestra al instante. En caso de fallo de caché, se verifica el disco a través de flutter_cache_manager: una consulta SQLite verifica si el archivo existe en la caché y si su TTL ha expirado. Si el archivo está actualizado — se lee del disco, se decodifica y se muestra. Si el archivo falta o el TTL ha expirado — se realiza una solicitud HTTP.
DefaultCacheManager proporciona emptyCache() (limpieza completa), cleanCache() (eliminar solo los expirados) y clearCacheWithAge() con una fecha personalizada. ImageCache se limpia automáticamente bajo presión de memoria o manualmente mediante imageCache.clear().
CachedNetworkImage está construido sobre la composición de widgets estándar de Flutter. La implementación interna utiliza ImageProvider para la carga asíncrona y StatefulWidget para la gestión del ciclo de vida.
imageUrl — parámetro obligatorio, la URL de la imagen (String o Uri). placeholder — widget mostrado durante la carga. errorWidget — widget en caso de error de carga. progressIndicatorBuilder — builder que recibe contexto, URL y DownloadProgress con los campos totalSize y downloadedSize.
CachedNetworkImageProvider — una implementación de ImageProvider que devuelve CachedNetworkStreamImage, que gestiona la descarga y el almacenamiento en caché. El proveedor se integra con ImageCache de Flutter y admite todas las capacidades estándar de ImageProvider: escalado, centrado y repetición.
flutter_cache_manager es la biblioteca subyacente al sistema de caché de CachedNetworkImage. Proporciona DefaultCacheManager con una base de datos SQLite configurada, TTL y límite de archivos. Si es necesario, se puede crear un CacheManager personalizado con parámetros únicos.
| Parámetro | Descripción | Valor por defecto |
|---|---|---|
| maxAgeCacheObject | Duración máxima de almacenamiento del archivo | 7 días |
| maxNrOfCacheObjects | Número máximo de archivos | 200 |
| key | Identificador único del gestor | “default” |
| repo | Tipo de almacenamiento de metadatos | CacheObjectRepository (SQLite) |
| fileService | Cliente HTTP para descargas | HttpFileService |
Se crea un CacheManager personalizado heredando de CacheManager con sobrescritura de métodos. Esto es útil cuando las imágenes necesitan almacenarse en un directorio separado o se requiere un cliente HTTP diferente. La instancia del gestor se pasa al parámetro cacheManager de CachedNetworkImage.
La base de datos SQLite de DefaultCacheManager se encuentra en el temporaryDirectory de la aplicación en la ruta `{key}/CacheObjects.db`. Contiene la tabla cacheObjects con los campos: key (URL), relativePath, url, creationDate, eTag, httpHeaders. Al limpiar entradas expiradas, se utiliza una consulta SQL con condición sobre maxAgeCacheObject.
CachedNetworkImage proporciona dos enfoques principales de carga: el widget CachedNetworkImage y CachedNetworkImageProvider para escenarios personalizados.
CachedNetworkImage — el enfoque principal. Simplemente pasa imageUrl y placeholder. El widget muestra automáticamente el placeholder hasta que se completa la carga y lo reemplaza con la imagen.
CachedNetworkImage(
imageUrl: "https://example.com/photo.jpg",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
width: 200,
height: 200,
fit: BoxFit.cover,
)
placeholder y errorWidget son funciones builder que aceptan contexto, URL y (para errorWidget) un objeto de error. Este enfoque permite mostrar diferentes marcadores según la URL o el tipo de error.
progressIndicatorBuilder — un parámetro que permite mostrar el progreso de descarga como porcentaje. DownloadProgress contiene totalSize (puede ser -1 si se desconoce) y downloadedSize.
CachedNetworkImage(
imageUrl: "https://example.com/large.jpg",
progressIndicatorBuilder: (context, url, downloadProgress) {
return Center(
child: SizedBox(
width: 50,
height: 50,
child: Stack(
alignment: Alignment.center,
children: [
CircularProgressIndicator(
value: downloadProgress.progress,
),
Text(
"\(downloadProgress.downloadedSize ~/ 1024) KB",
),
],
),
),
};
},
imageBuilder: (context, imageProvider) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
),
),
};
},
)
imageBuilder — un parámetro opcional que permite personalizar la visualización de la imagen: añadir esquinas redondeadas, sombras, decoraciones. El ejemplo utiliza DecorationImage con BorderRadius para esquinas redondeadas.
CachedNetworkImageProvider — un proveedor para Image o DecorationImage sin usar el widget CachedNetworkImage. Útil cuando se trabaja con BoxDecoration, FadeInImage o widgets de imagen personalizados.
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: CachedNetworkImageProvider(
"https://example.com/bg.jpg",
maxWidthBytes: 2048,
maxHeightBytes: 2048,
),
fit: BoxFit.cover,
),
),
)
El parámetro imageBuilder en CachedNetworkImage permite sobrescribir el widget Image estándar con una implementación personalizada. En lugar de mostrar directamente la Image, puedes usar un Container con decoración, ClipRRect para recortar, o Ink.image para efectos de ripple. imageBuilder recibe contexto y ImageProvider de la imagen lista, dando control total sobre el renderizado.
Parámetros adicionales: memCacheWidth y memCacheHeight limitan el tamaño de la imagen en caché en RAM, reduciendo la carga en ImageCache de Flutter. cacheKey permite establecer una clave de caché personalizada en lugar de la URL, útil para imágenes con tokens de autorización en la URL (los parámetros de consulta cambian en cada solicitud pero el contenido sigue siendo el mismo).
El widget estándar Image.network carga la imagen en cada reconstrucción del widget sin guardarla en disco. CachedNetworkImage añade almacenamiento en caché de archivos, indicadores de progreso y manejo de errores, pero añade una dependencia de flutter_cache_manager y SQLite.
| Criterio | Image.network | CachedNetworkImage |
|---|---|---|
| Caché en disco | No (solo caché en memoria de Flutter) | Sí (SQLite + archivos) |
| Progreso | No | progressIndicatorBuilder |
| Widget de error | Solo placeholder rojo en debug | errorWidget personalizado |
| TTL de caché | No aplica | Configurable (7 días por defecto) |
| Dependencias | Ninguna (integrado en Flutter) | cached_network_image + flutter_cache_manager + sqflite |
| Acceso sin conexión | No | Sí (con archivos previamente cargados) |
| Tamaño de compilación | 0 KB adicionales | ~300 KB adicionales |
Para proyectos donde la capacidad sin conexión y el ahorro de ancho de banda son importantes, CachedNetworkImage es la opción clara. Para pantallas simples y únicas (por ejemplo, onboarding o splash), Image.network no requiere dependencias adicionales.
CachedNetworkImage se agrega como una dependencia estándar de pub.dev. Después de la instalación, el widget está listo para usar. flutter_cache_manager se incluye como dependencia transitiva.
// pubspec.yaml
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.4.1
Por defecto, se utiliza DefaultCacheManager con configuración: TTL = 7 días, máx 200 archivos. Para cambiar los parámetros globales, se crea una instancia de CacheManager personalizada con Config, donde se sobrescriben maxAgeCacheObject, maxNrOfCacheObjects y repo.
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
final customCacheManager = CacheManager(
Config(
"custom_images",
stalePeriod: Duration(days: 14),
maxNrOfCacheObjects: 500,
repo: JsonCacheInfoRepository(
databaseName: "custom_images_cache.db",
),
),
);
// Usando un gestor personalizado:
CachedNetworkImage(
cacheManager: customCacheManager,
imageUrl: url,
// ...
)
maxWidthBytes y maxHeightBytes — parámetros opcionales para limitar el tamaño del archivo en caché. Esto es útil para ahorrar espacio en disco cuando la imagen original es más grande que el tamaño de pantalla requerido.
Preguntas frecuentes
CachedNetworkImage es un widget de Flutter para cargar imágenes de red con almacenamiento en caché automático en disco. Sirve para ahorrar ancho de banda, trabajar en modo sin conexión y mostrar el progreso de descarga, algo que el Image.network estándar no proporciona.
Agrega cached_network_image: ^3.4.1 en la sección de dependencias de pubspec.yaml y ejecuta flutter pub get. Luego importa el paquete en tu archivo: import ‘package:cached_network_image/cached_network_image.dart’.
Crea un CacheManager personalizado con Config donde el parámetro stalePeriod se especifique como Duration. Pasa el gestor creado al parámetro cacheManager del widget CachedNetworkImage. Por defecto, los archivos se almacenan durante 7 días.
Llama a DefaultCacheManager().emptyCache() para una limpieza completa de todos los archivos. Para eliminar solo los expirados, usa cleanCache(). Un gestor personalizado se limpia llamando a emptyCache en su instancia.
Sí, CachedNetworkImage es compatible con Android, iOS, Web, macOS, Windows y Linux. Una API unificada garantiza un comportamiento consistente en todas las plataformas, y el almacenamiento en caché funciona a través de flutter_cache_manager, adaptado para cada sistema operativo.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también