What is the difference between precacheImage and CachedNetworkImage in Flutter?

#flutter#images#caching#performance#precache

Answer

Overview

  • text
    precacheImage()
    — A built-in Flutter function that pre-loads an image into memory cache (RAM) before the widget builds
  • text
    CachedNetworkImage
    — A third-party widget (package:
    text
    cached_network_image
    ) that downloads and caches images to disk + memory with placeholder/error support

precacheImage() — Built-in Memory Pre-loading

What It Does

Pre-fetches an image and stores it in Flutter's in-memory

text
ImageCache
before the widget that displays it is built. This prevents the flicker/pop-in when an image appears for the first time.

Usage

dart
class _MyScreenState extends State<MyScreen> {
  
  void didChangeDependencies() {
    super.didChangeDependencies();
    // Pre-cache images before build
    precacheImage(
      const NetworkImage('https://example.com/hero.jpg'),
      context,
    );
    precacheImage(
      const AssetImage('assets/images/logo.png'),
      context,
    );
  }

  
  Widget build(BuildContext context) {
    return Image.network('https://example.com/hero.jpg');
    // Loads instantly from memory cache!
  }
}

Pre-cache Before Navigation

dart
// Pre-cache the next screen's images before navigating
Future<void> _goToProfile() async {
  await precacheImage(
    const NetworkImage('https://example.com/profile-bg.jpg'),
    context,
  );
  if (mounted) {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (_) => const ProfileScreen()),
    );
  }
}

Key Characteristics

  • Cache: Memory only (RAM)
  • Persistence: Lost when app closes or cache evicts (default: 1000 images, 100MB)
  • Works with:
    text
    NetworkImage
    ,
    text
    AssetImage
    ,
    text
    FileImage
    — any
    text
    ImageProvider
  • No UI: It's a function, not a widget — no placeholder/error support
  • Returns:
    text
    Future<void>
    that completes when image is decoded and cached

CachedNetworkImage — Disk + Memory Caching Widget

Installation

yaml
# pubspec.yaml
dependencies:
  cached_network_image: ^3.4.1

Basic Usage

dart
import 'package:cached_network_image/cached_network_image.dart';

CachedNetworkImage(
  imageUrl: 'https://example.com/photo.jpg',
  placeholder: (context, url) => const CircularProgressIndicator(),
  errorWidget: (context, url, error) => const Icon(Icons.error),
)

With Progress Indicator

dart
CachedNetworkImage(
  imageUrl: 'https://example.com/photo.jpg',
  progressIndicatorBuilder: (context, url, progress) =>
      CircularProgressIndicator(value: progress.progress),
  errorWidget: (context, url, error) => const Icon(Icons.error),
  fadeInDuration: const Duration(milliseconds: 200),
  maxWidthDiskCache: 800,
  maxHeightDiskCache: 600,
)

As an ImageProvider

dart
Image(
  image: CachedNetworkImageProvider(
    'https://example.com/photo.jpg',
  ),
)

Key Characteristics

  • Cache: Disk + Memory (survives app restart)
  • Persistence: Configurable max age and max objects
  • Offline support: Yes — serves from disk when offline
  • UI: Built-in placeholder, error widget, progress indicator
  • Dependencies:
    text
    flutter_cache_manager
    ,
    text
    sqflite

Key Differences

Feature
text
precacheImage()
text
CachedNetworkImage
TypeFunction (built-in)Widget (package)
Cache locationMemory (RAM) onlyDisk + Memory
Survives app restart❌ No✅ Yes
Offline support❌ No✅ Yes
Placeholder widget❌ No (not a widget)✅ Yes
Error widget❌ No✅ Yes
Progress indicator❌ No✅ Yes
When image loadsBefore widget builds (pre-fetch)When widget is mounted
Works with assets✅ Yes (any
text
ImageProvider
)
❌ No (network only)
External dependenciesNone
text
flutter_cache_manager
,
text
sqflite
Cache controlLimited (
text
ImageCache
size)
Full (max age, max objects)

When to Use Each

Use
text
precacheImage()
When:

  • You want zero flicker when an image first appears (hero images, splash)
  • You know which images the next screen will need
  • You're working with asset images
  • You don't need disk persistence
  • You want no external dependencies

Use
text
CachedNetworkImage
When:

  • You need offline image support
  • You want built-in placeholder and error widgets
  • You're displaying many network images (list/grid views)
  • You need download progress indication
  • You want images cached across app restarts

Using Them Together

Yes! Combine

text
CachedNetworkImageProvider
with
text
precacheImage()
for both disk caching AND pre-loading:

dart

void didChangeDependencies() {
  super.didChangeDependencies();
  // Pre-cache into memory AND persist to disk
  precacheImage(
    CachedNetworkImageProvider(
      'https://example.com/next-screen-hero.jpg',
    ),
    context,
  );
}


Widget build(BuildContext context) {
  return CachedNetworkImage(
    imageUrl: 'https://example.com/next-screen-hero.jpg',
    // Loads instantly from memory (precached)
    // Also persisted to disk for offline use
    placeholder: (context, url) => const CircularProgressIndicator(),
    errorWidget: (context, url, error) => const Icon(Icons.error),
  );
}

Decision Guide

dart
// Need instant display with no flicker?
//   → precacheImage() before navigation

// Need offline support + placeholder UI?
//   → CachedNetworkImage widget

// Need BOTH instant display AND disk persistence?
//   → precacheImage(CachedNetworkImageProvider(...), context)

// Displaying a list of network images?
//   → CachedNetworkImage (handles caching per-item)

// Pre-loading asset images?
//   → precacheImage(AssetImage(...), context)

Best Practice: For hero images or images you know will be displayed immediately, combine both:

text
precacheImage()
with
text
CachedNetworkImageProvider
gives you instant display + disk persistence + offline support.

Learn more at precacheImage API and cached_network_image package.