Progressive Image Loading with CachedNetworkImage and BlurHash in Flutter
Jul 31, 2025



Summary
Summary
Summary
Summary
This tutorial covers progressive image loading in Flutter using CachedNetworkImage and BlurHash. You’ll learn to generate and include BlurHash strings, decode them as blurred placeholders, customize animations and error widgets, and apply best practices for caching and performance. By the end, your app will display polished, low-res previews instead of blank or spinners.
This tutorial covers progressive image loading in Flutter using CachedNetworkImage and BlurHash. You’ll learn to generate and include BlurHash strings, decode them as blurred placeholders, customize animations and error widgets, and apply best practices for caching and performance. By the end, your app will display polished, low-res previews instead of blank or spinners.
This tutorial covers progressive image loading in Flutter using CachedNetworkImage and BlurHash. You’ll learn to generate and include BlurHash strings, decode them as blurred placeholders, customize animations and error widgets, and apply best practices for caching and performance. By the end, your app will display polished, low-res previews instead of blank or spinners.
This tutorial covers progressive image loading in Flutter using CachedNetworkImage and BlurHash. You’ll learn to generate and include BlurHash strings, decode them as blurred placeholders, customize animations and error widgets, and apply best practices for caching and performance. By the end, your app will display polished, low-res previews instead of blank or spinners.
Key insights:
Key insights:
Key insights:
Key insights:
Understanding BlurHash: Converts images into compact ASCII strings for fast, low-res previews.
Implementing Progressive Loading: Use CachedNetworkImage with a BlurHash placeholderBuilder for seamless transitions.
Customizing Placeholders and Error Widgets: Adjust decoding resolution, animations, and fallback widgets to fit your design.
Best Practices: Precompute hashes, store metadata, and tune cache settings for production apps.
Performance Tuning: Control decoding dimensions and fade durations to balance quality and speed.
Introduction
Progressive image loading improves perceived performance in mobile development by displaying a low-resolution placeholder while the full image loads. In Flutter, CachedNetworkImage handles caching and network requests, but placeholders typically rely on static or loading spinners. BlurHash bridges that gap by generating a compact string representation of an image, which you can decode into a blurred preview. In this tutorial, you’ll learn how to integrate BlurHash with CachedNetworkImage to deliver smooth, visually pleasing placeholders for your Flutter app.
Understanding BlurHash
BlurHash is an algorithm that converts an image into a short ASCII string. This string captures color and brightness information in a coarse grid. You send the BlurHash string alongside your image URL. On the client side, a small decoding function reconstructs a blurred version of the original. The result is a lightweight, automatically generated preview that fits in memory and network budgets.
Key points:
The BlurHash string is typically generated on the server or build step.
Decoding in Flutter requires only milliseconds.
The decoded blur is displayed as a placeholder until the high-resolution image appears.
Implementing Progressive Loading with CachedNetworkImage and BlurHash
First, add dependencies in your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.2.0
blurhash_flutter
Import the packages where you render images:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:blurhash_flutter/blurhash_flutter.dart';
Use CachedNetworkImage with a custom placeholderBuilder that decodes the BlurHash string:
CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => BlurHash(
hash: blurHash, // your precomputed string
imageFit: BoxFit.cover,
),
errorWidget: (context, url, error) => Icon(Icons.error_outline),
fit: BoxFit.cover,
);
Explanation:
imageUrl: URL of the full-resolution image.
placeholder: A widget displayed while loading. Here we instantiate BlurHash with your hash.
errorWidget: A fallback icon if the network request fails.
fit: Ensures the image and placeholder fill the container.
Customizing Placeholders and Error Widgets
You can adjust the placeholder decoding resolution, colors, and fade durations for a more refined effect. For example, wrap BlurHash in an AnimatedOpacity to cross-fade smoothly:
Widget blurredPlaceholder(String blurHash) {
return AnimatedOpacity(
opacity: 1.0,
duration: Duration(milliseconds: 500),
child: BlurHash(
hash: blurHash,
decodingWidth: 32,
decodingHeight: 32,
imageFit: BoxFit.cover,
),
);
}
CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (ctx, url) => blurredPlaceholder(blurHash),
errorWidget: (ctx, url, err) => Center(
child: Container(
color: Colors.grey[200],
child: Icon(Icons.broken_image, size: 48),
),
),
);
Tips:
decodingWidth/decodingHeight control blur detail vs performance.
Use BoxDecoration with a background color that matches your design.
Fade in the high-res image by specifying fadeInDuration.
Best Practices
Precompute BlurHash strings during your asset pipeline or server build step. Avoid computing on the client at runtime for production.
Store the BlurHash alongside each image in your database or metadata service.
Use a consistent grid size for BlurHash (e.g., 4×3) to balance placeholder quality and string length.
Cache network images aggressively by configuring cache sizes and eviction policies in CachedNetworkImage.
Test on varying network conditions using Flutter’s network profiler or external tools.
Applying these best practices ensures your placeholders always appear quickly, even on slow connections.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Progressive image loading with CachedNetworkImage and BlurHash elevates user experience in Flutter mobile development. By displaying a low-resolution, blurred preview before the full image arrives, you avoid blank states and loading spinners. Integrating BlurHash requires minimal code changes and leverages existing caching mechanisms. Follow the steps and best practices outlined above to create smooth, polished image transitions in your Flutter apps.
Introduction
Progressive image loading improves perceived performance in mobile development by displaying a low-resolution placeholder while the full image loads. In Flutter, CachedNetworkImage handles caching and network requests, but placeholders typically rely on static or loading spinners. BlurHash bridges that gap by generating a compact string representation of an image, which you can decode into a blurred preview. In this tutorial, you’ll learn how to integrate BlurHash with CachedNetworkImage to deliver smooth, visually pleasing placeholders for your Flutter app.
Understanding BlurHash
BlurHash is an algorithm that converts an image into a short ASCII string. This string captures color and brightness information in a coarse grid. You send the BlurHash string alongside your image URL. On the client side, a small decoding function reconstructs a blurred version of the original. The result is a lightweight, automatically generated preview that fits in memory and network budgets.
Key points:
The BlurHash string is typically generated on the server or build step.
Decoding in Flutter requires only milliseconds.
The decoded blur is displayed as a placeholder until the high-resolution image appears.
Implementing Progressive Loading with CachedNetworkImage and BlurHash
First, add dependencies in your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.2.0
blurhash_flutter
Import the packages where you render images:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:blurhash_flutter/blurhash_flutter.dart';
Use CachedNetworkImage with a custom placeholderBuilder that decodes the BlurHash string:
CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => BlurHash(
hash: blurHash, // your precomputed string
imageFit: BoxFit.cover,
),
errorWidget: (context, url, error) => Icon(Icons.error_outline),
fit: BoxFit.cover,
);
Explanation:
imageUrl: URL of the full-resolution image.
placeholder: A widget displayed while loading. Here we instantiate BlurHash with your hash.
errorWidget: A fallback icon if the network request fails.
fit: Ensures the image and placeholder fill the container.
Customizing Placeholders and Error Widgets
You can adjust the placeholder decoding resolution, colors, and fade durations for a more refined effect. For example, wrap BlurHash in an AnimatedOpacity to cross-fade smoothly:
Widget blurredPlaceholder(String blurHash) {
return AnimatedOpacity(
opacity: 1.0,
duration: Duration(milliseconds: 500),
child: BlurHash(
hash: blurHash,
decodingWidth: 32,
decodingHeight: 32,
imageFit: BoxFit.cover,
),
);
}
CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (ctx, url) => blurredPlaceholder(blurHash),
errorWidget: (ctx, url, err) => Center(
child: Container(
color: Colors.grey[200],
child: Icon(Icons.broken_image, size: 48),
),
),
);
Tips:
decodingWidth/decodingHeight control blur detail vs performance.
Use BoxDecoration with a background color that matches your design.
Fade in the high-res image by specifying fadeInDuration.
Best Practices
Precompute BlurHash strings during your asset pipeline or server build step. Avoid computing on the client at runtime for production.
Store the BlurHash alongside each image in your database or metadata service.
Use a consistent grid size for BlurHash (e.g., 4×3) to balance placeholder quality and string length.
Cache network images aggressively by configuring cache sizes and eviction policies in CachedNetworkImage.
Test on varying network conditions using Flutter’s network profiler or external tools.
Applying these best practices ensures your placeholders always appear quickly, even on slow connections.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
Progressive image loading with CachedNetworkImage and BlurHash elevates user experience in Flutter mobile development. By displaying a low-resolution, blurred preview before the full image arrives, you avoid blank states and loading spinners. Integrating BlurHash requires minimal code changes and leverages existing caching mechanisms. Follow the steps and best practices outlined above to create smooth, polished image transitions in your Flutter apps.
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Build Flutter Apps Faster with Vibe Studio
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.
Vibe Studio is your AI-powered Flutter development companion. Skip boilerplate, build in real-time, and deploy without hassle. Start creating apps at lightning speed with zero setup.











