Boosting Flutter Web Performance: Caching with Service Workers
FlutterPulseThis article was translated specially for the channel FlutterPulseYou'll find lots of interesting things related to Flutter on this channel. Don't hesitate to subscribe!π
Delivering a fast and responsive Flutter web app is essential, especially as users expect instant loading times and offline support. One ofβ¦
Delivering a fast and responsive Flutter web app is essential, especially as users expect instant loading times and offline support. One of the most effective ways to achieve this is by using service workers for caching. Flutter automatically generates a service worker during web builds, but you can customize it to improve performance, reduce network calls, and enable offline access.
This article explains how service workers work in Flutter Web, how caching improves performance, and how you can build your own customized caching strategy.
π What Is a Service Worker?
A service worker is a background script that runs separately from your main web page. It can:
- Intercept and manage network requests
- Cache files to improve loading speed
- Serve assets when offline
- Enable Progressive Web App (PWA) behavior
In Flutter Web, the service worker plays a crucial role in making your app load faster and work offline.
π How Flutter Web Uses Service Workers
Whenever you run:
flutter build web
Flutter generates a file called flutter_service_worker.js inside the build/web/ directory. This file is responsible for:
- Pre-caching your app shell (
main.dart.js) - Saving static assets (images, fonts, JSONs)
- Caching
index.htmlfor offline startup - Loading cached files when the network is slow or offline
Flutter uses a hashing strategy so that users automatically receive new versions when you deploy them.
β‘ Why Caching Matters in Flutter Web
Caching provides multiple performance and reliability benefits:
- Faster Load Times β Files load directly from cache instead of being downloaded repeatedly.
- Offline Functionality β Your web app can launch even without an internet connection.
- Reduced Data Usage β Cached resources reduce bandwidth consumption.
- Better User Experience β Users get smooth, consistent access regardless of network conditions.
ποΈ Default Caching Strategy in Flutter
Flutter automatically caches:
main.dart.js(app code)assets/folder (images, fonts, JSON files)index.htmlmanifest.json
It uses a cache-first strategy for these assets. When a new version is deployed, Flutter detects changes via content hashes and replaces old cache entries.
π οΈ Custom Service Worker with Advanced Caching
To gain more control, you can write your own service worker that caches core assets, API requests, and provides offline fallback.
Custom Service Worker Example:
const CACHE_NAME = 'my-flutter-app-v1';
const API_CACHE = 'api-cache-v1';
const ASSETS_TO_CACHE = [
'/',
'/index.html',
'/main.dart.js',
'/flutter.js',
'/assets/assets/logo.png',
'/assets/AssetManifest.json',
'/assets/FontManifest.json',
'/manifest.json'
];
// Install: Cache core assets
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ASSETS_TO_CACHE);
})
);
self.skipWaiting();
});
// Activate: Clean old caches
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(
keys.filter(key => key !== CACHE_NAME && key !== API_CACHE)
.map(key => caches.delete(key))
);
})
);
self.clients.claim();
});
// Fetch: Cache-first for assets, network-first for API
self.addEventListener('fetch', (event) => {
const url = event.request.url;
if (url.includes('/api/')) {
event.respondWith(cacheApiRequest(event.request));
} else if (ASSETS_TO_CACHE.some(asset => url.endsWith(asset))) {
event.respondWith(cacheFirst(event.request));
} else {
event.respondWith(networkFirst(event.request));
}
});
// Cache-first strategy
async function cacheFirst(request) {
const cached = await caches.match(request);
return cached ?? fetch(request);
}
// Network-first with fallback
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
return networkResponse;
} catch (e) {
const cached = await caches.match(request);
return cached || new Response('Offline', { status: 503 });
}
}
// API: Stale-while-revalidate
async function cacheApiRequest(request) {
const cache = await caches.open(API_CACHE);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(async (networkResponse) => {
cache.put(request, networkResponse.clone());
return networkResponse;
}).catch(() => cachedResponse);
return cachedResponse || fetchPromise;
}
How to Use This Service Worker
Step 1: Save this file as:
web/custom_service_worker.js
Step 2: Register it in index.html at the end of the <body> tag:
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('custom_service_worker.js')
.then(reg => console.log('SW registered:', reg.scope))
.catch(err => console.error('SW registration failed:', err));
}
</script>
This ensures your Flutter app uses the custom caching logic.
π Caching Strategies You Can Use
- Cache First β Loads from cache β falls back to network.
Great for images, fonts. - Network First β Tries network β fallback to cache.
Great for news feeds, dashboards. - Stale-While-Revalidate β Returns cached version instantly while updating in the background.
Best for user feeds, app content. - Cache Only / Network Only β Used in rare or specific scenarios.
π Real Advantages Seen in Production
Using caching with service workers provides tangible improvements:
- 40β90% faster load times β your app feels instant to users.
- 50% fewer API calls β reduces server load and bandwidth.
- Full offline functionality β users can access content even without internet.
- Improved Core Web Vitals (LCP, FCP) β faster rendering and better perceived performance.
π Making Flutter Web a PWA
Service workers are essential for PWAs. Flutter already supports PWAs, but this custom SW improves:
- Caching API responses
- Offline access
- Update handling
To complete PWA setup:
- Add proper icons to
manifest.json - Host over HTTPS
- Register your service worker
π Final Thoughts
Caching using service workers is one of the easiest ways to boost Flutter Web performance. While Flutter provides a default service worker, using a custom service worker like this one allows:
- Advanced asset caching
- API caching with stale-while-revalidate
- Offline fallback and improved user experience
If you're building a Flutter Web app or PWA, this setup ensures fast, reliable, and modern web performance.