advanced_cache_network_image 0.0.3
advanced_cache_network_image: ^0.0.3 copied to clipboard
Advanced Flutter image caching with LRU memory cache, disk cache, download queue and prefetch support.
advanced_cache_network_image #
Advanced Flutter network image loading with memory + disk cache, request deduplication, progress callbacks, queue-based concurrency, and retry support.
Features #
- Widget-first API:
AdvancedCacheNetworkImage - Memory caching (
MemoryCache) - Disk caching in temporary directory (
DiskCache) - Request deduplication (same URL shares one in-flight request)
- Shared progress listeners for duplicate requests
- Download queue with configurable concurrency (
ViewportPriorityQueue.maxConcurrent, default3) - Retry with exponential backoff for transient network/server failures
- Optional decode sizing (
targetWidth,targetHeight) for large images - Placeholder, progress, error, and custom image builder support
- Prefetch support through
ImageLoader.prefetch(...)
Install #
dependencies:
advanced_cache_network_image: ^0.0.3
Then run:
flutter pub get
Basic Usage #
import 'package:advanced_cache_network_image/advanced_cache_network_image.dart';
AdvancedCacheNetworkImage(
url: 'https://picsum.photos/1200/800',
width: 300,
height: 200,
fit: BoxFit.cover,
radius: 12,
)
Usage with Progress + Error UI #
AdvancedCacheNetworkImage(
url: 'https://picsum.photos/800/500',
height: 220,
fit: BoxFit.cover,
progressBuilder: (context, progress) {
return Center(
child: CircularProgressIndicator(
value: progress == 0 ? null : progress,
),
);
},
errorWidget: const Center(
child: Icon(Icons.broken_image),
),
)
Resize During Decode #
AdvancedCacheNetworkImage(
url: 'https://picsum.photos/3840/2160',
targetWidth: 800,
targetHeight: 450,
fit: BoxFit.cover,
)
Prefetch Example #
import 'package:advanced_cache_network_image/advanced_cache_network_image.dart';
final loader = ImageLoader();
await loader.prefetch('https://picsum.photos/1200/800');
You can also control cache manually:
await loader.evict('https://picsum.photos/1200/800'); // remove one URL
loader.clearMemoryCache(); // clear memory cache only
Advanced Customization #
import 'package:advanced_cache_network_image/advanced_cache_network_image.dart';
final loader = ImageLoader(
timeout: const Duration(seconds: 20),
maxRetries: 5,
baseDelay: const Duration(milliseconds: 400),
maxConcurrentDownloads: 6,
);
final cancelToken = CancelToken();
AdvancedCacheNetworkImage(
url: 'https://example.com/image.jpg',
imageLoader: loader,
cancelToken: cancelToken,
useMemoryCache: true,
useDiskCache: true,
cacheDuration: const Duration(days: 3),
);
// later: cancel if needed
cancelToken.cancel();
What You Can Update #
1) Widget-level options (AdvancedCacheNetworkImage) #
- URL and rendering:
url,fit,width,height,radius - Loading UI:
placeholder,progressBuilder,errorWidget - Decode size:
targetWidth,targetHeight - Animation:
enableFade,fadeDuration - Cache usage per widget:
useMemoryCache,useDiskCache,cacheDuration - Advanced wiring:
imageLoader,cancelToken,imageBuilder
2) Loader-level options (ImageLoader) #
- Network behavior:
timeout,maxRetries,baseDelay - Download concurrency:
maxConcurrentDownloads - Cache lifecycle:
prefetch(url)evict(url, memory: true, disk: true)clearMemoryCache()
3) Global queue option (ViewportPriorityQueue) #
- Update queue concurrency at runtime:
ViewportPriorityQueue.maxConcurrent = 6;
Practical Pattern #
final loader = ImageLoader(
timeout: const Duration(seconds: 20),
maxRetries: 4,
maxConcurrentDownloads: 5,
);
AdvancedCacheNetworkImage(
url: 'https://example.com/image.jpg',
imageLoader: loader,
useMemoryCache: true,
useDiskCache: true,
cacheDuration: const Duration(days: 7),
targetWidth: 900,
enableFade: true,
);
Widget Parameters #
url(required): image URLfit:BoxFitfor renderingplaceholder: widget shown while loadingprogressBuilder: builder with progress (0.0to1.0)errorWidget: widget shown on failurewidth,height: optional layout sizingradius: border radius applied withClipRRecttargetWidth,targetHeight: decode size hintscacheDuration: disk cache expiration check (when used in file-based load flow)useMemoryCache,useDiskCache: cache togglesenableFade,fadeDuration: animated transitionsimageBuilder: full control over final image renderingimageLoader: inject your ownImageLoaderinstancecancelToken: cancel an in-flight request
Notes #
- Disk cache files are stored in the platform temporary directory.
- Memory cache is currently a simple in-memory map (no LRU eviction yet).
prefetchand low-level cache/network APIs are available fromImageLoader.
Troubleshooting #
- Invalid URL
Cause: malformed URL, DNS issue, or non-200 server response.
Fix: verify the URL in a browser/Postman, ensure it starts with
http://orhttps://, and provide anerrorWidgetto handle failures gracefully. - Cache seems stale
Cause: cached bytes are reused from memory/disk.
Fix: use a cache-busting query (for example
?v=timestamp), set an appropriatecacheDurationin file-based flows, or clear/restart app state during development. - Progress stuck at indeterminate
Cause: server does not send
content-length, so total size is unknown. Fix: this is expected for some endpoints; keep showing indeterminate progress (value: null) until completion, or switch to a different endpoint/CDN that returnscontent-length.
Example App #
See the runnable sample in:
example/lib/main.dart- The example screen now includes a live customization panel (toggles + sliders) so you can test most settings directly.
License #
MIT - see LICENSE.