Precaching
Background activation-first precaching with IndexedDB checkpoint resume, progress reporting, and version-aware reset.
If you're coming from Workbox: Workbox blocks the
installevent until all assets are cached — the SW can't activate until precaching finishes. Swoff activates immediately and precaches in the background. If the SW is terminated mid-way, it resumes from the last checkpoint instead of starting over. See the comparison table below.
Status
On by default. After swoff init, the generated SW precaches all scanned build assets, navigation fallback pages, and the PWA manifest.
See the Precaching Architecture for the design rationale — background activation-first, checkpoint system, progress reporting, client-initiated resume, version-aware reset, and reset protocol.
What gets precached
Three sources feed into the ASSETS_TO_CACHE list:
| Source | How it's configured | Example |
|---|---|---|
| Build output directories | build.precacheDirs | .next/static/* → /_next/static/*.js |
| Navigation fallback pages | serviceWorker.navigation.fallback + rules[].fallback | /index.html, /offline.html |
| Explicit route list | serviceWorker.navigation.precacheRoutes | ["/", "/about", "/blog"] |
| PWA manifest | Automatically included when features.pwa.enabled | /manifest.json |
All URLs are deduplicated at build time — if the same URL appears from multiple sources, it's only precached once.
Framework adapter
The useSwoffPrecache adapter exposes { progress } — a number from 0 to 100:
function PrecacheIndicator() {
const { progress } = useSwoffPrecache();
if (progress === 0 || progress === 100) return null;
return <div>Precaching: {progress}%</div>;
}If your framework already has this adapter (React, Vue, Svelte), the CLI generates it into swoff/adapters/. To create adapters for any other framework, see the Blueprint.
Config
{
"features": {
"serviceWorker": {
"precache": {
"concurrency": 3,
"delayMs": 50
}
},
"pwa": {
"enabled": true
}
},
"build": {
"precacheDirs": {
".next/static": {
"prefix": "/_next/static"
}
}
}
}features.serviceWorker.precache
| Field | Type | Default | Description |
|---|---|---|---|
concurrency | number | 1 | Number of assets to download simultaneously in each batch. Higher values speed up large precaches but may increase bandwidth contention. |
delayMs | number | 0 | Delay in milliseconds between starting individual requests within a batch. Spaces out requests to avoid network saturation on initial load. |
build.precacheDirs
Each key is a filesystem path relative to project root. See the Service Worker config for all options (prefix, matchExtensions, stripExtensions, stripSuffixes, excludeDirs, excludeFiles).
Comparison
| Aspect | Swoff | Workbox | Serwist |
|---|---|---|---|
| Timing | After activate (background, non-blocking) | During install (blocks activation) | During install (blocks activation) |
| Install event | skipWaiting() only, zero downloads | Downloads all assets, blocks until complete | Downloads all assets, blocks until complete |
| Checkpoint/resume | ✅ IndexedDB checkpoint — survives termination | ❌ Full re-download on SW restart | ❌ Full re-download on SW restart |
| Per-asset progress events | ✅ Built-in: SW_PROGRESS → sw-progress DOM event | 🟡 Via workbox.progressReporting plugin | 🟡 Limited |
| Concurrency control | ✅ precache.concurrency + precache.delayMs | 🟡 maxParallelRequests (plugin only) | ❌ |
| Inter-request spacing | ✅ delayMs between requests in a batch | ❌ | ❌ |
| Client-initiated resume | ✅ Visibility change + online → RESUME_PRECACHE | ❌ | ❌ |
| Version-aware reset | ✅ Content hash of asset list; auto-reset on deploy | 🟡 Revision manifest mismatch | 🟡 Revision manifest mismatch |
| Full re-cache without re-registration | ✅ RESET_CACHE message via MessageChannel | ❌ | ❌ |
| Framework adapters | ✅ useSwoffPrecache (14 frameworks) | 🟡 registerSW() only | ❌ |
Related
- Precaching Architecture — design rationale, checkpoint system, reset protocol
- Service Worker guide — SW lifecycle, versioning, build step
- Caching System architecture — precache vs runtime cache interactions
- Config: serviceWorker.precache — full schema