Asset Caching
Contains a breaking change compared to v1.0.x
Asset caching provides automatic precaching and efficient serving of your application's static assets managed by Symfony's AssetMapper component. This ensures your CSS, JavaScript, images, and other static files are available offline and load instantly from the cache.
How It Works
The asset cache feature automatically:
Discovers assets: Scans all assets registered with Symfony AssetMapper
Filters by regex: Only includes assets matching the regex pattern
Precaches on install: Downloads and caches all matching assets when the service worker installs
Serves from cache: Uses CacheFirst strategy for optimal performance
Manages expiration: Automatically removes old cached assets based on your configuration
Default Configuration
pwa:
serviceworker:
workbox:
asset_cache:
enabled: true # Enable asset caching
regex: '/\.(css|js|json|xml|txt|map|ico|png|jpe?g|gif|svg|webp|bmp)$/' # Default pattern
cache_name: null # Auto-generated: 'asset-cache'
max_age: null # Default: 1 year (31536000 seconds)
max_entries: 60 # Maximum number of cached assetsBy default, the cache includes all common asset types:
Stylesheets:
.cssScripts:
.jsData:
.json,.xml,.txtSource maps:
.mapIcons:
.icoImages:
.png,.jpg,.jpeg,.gif,.svg,.webp,.bmp
Configuration Options
enabled
Type: boolean Default: true
Enable or disable asset caching entirely.
asset_cache:
enabled: false # Disable asset cachingregex
Type: string (regex pattern) Default: /\.(css|js|json|xml|txt|map|ico|png|jpe?g|gif|svg|webp|bmp)$/
Regular expression to filter which assets should be cached. Only assets whose public path matches this pattern will be included.
Examples:
Cache only CSS and JavaScript:
asset_cache:
regex: '/\.(css|jsx?)$/'Cache only images:
asset_cache:
regex: '/\.(png|jpe?g|gif|svg|webp)$/'Cache everything:
asset_cache:
regex: '/.*/'Exclude source maps:
asset_cache:
regex: '/\.(css|js|json|xml|txt|ico|png|jpe?g|gif|svg|webp|bmp)$/'cache_name
Type: string|null Default: null (auto-generates "asset-cache")
Custom name for the cache. Useful for debugging and cache management.
asset_cache:
cache_name: 'my-app-assets'max_age
Type: string|integer|null Default: null (1 year)
Maximum age for cached assets. Accepts human-readable format or seconds.
Examples:
asset_cache:
max_age: '30 days' # Human-readable
max_age: 2592000 # 30 days in seconds
max_age: null # Use default (1 year)max_entries
Type: integer Default: 60
Maximum number of asset entries to keep in cache. When exceeded, oldest entries are removed first. The actual limit is max_entries * 2 to account for growth between cleanups.
asset_cache:
max_entries: 100 # Allow up to 100 cached assetsIntegration with AssetMapper
The asset cache works seamlessly with Symfony's AssetMapper:
What Gets Cached
All assets registered through AssetMapper that match the regex pattern:
// These assets will be automatically discovered and cached
// if they match the regex pattern
#[AssetMapper]
class MyController
{
// app.css will be cached (matches .css)
// app.js will be cached (matches .js)
}Asset Versioning
AssetMapper automatically versions assets (e.g., app.a1b2c3.css). When you update an asset:
New version gets a new filename
Service worker detects the change
New version is precached on next service worker update
Old version is removed from cache
Public Path Resolution
The cache automatically uses the correct public path configured in AssetMapper:
# config/packages/asset_mapper.yaml
framework:
asset_mapper:
public_prefix: '/build' # Assets served from /build/The service worker will cache all assets under /build/ that match the regex.
Caching Strategy
Asset caching uses the CacheFirst strategy:
// Generated service worker code
workbox.routing.registerRoute(
({url}) => url.pathname.startsWith('/assets'),
new workbox.strategies.CacheFirst({
cacheName: 'asset-cache',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 120, // max_entries * 2
maxAgeSeconds: 31536000, // 1 year
})
]
})
);Why CacheFirst?
Static assets rarely change
Versioned filenames ensure new versions are fetched
Maximum performance: no network delay
Works offline immediately
Complete Examples
Minimal Configuration
Use defaults for most applications:
pwa:
serviceworker:
workbox:
asset_cache:
enabled: true # Everything else uses defaultsCSS and JavaScript Only
Cache only stylesheets and scripts:
pwa:
serviceworker:
workbox:
asset_cache:
enabled: true
regex: '/\.(css|jsx?)$/'
cache_name: 'app-code'
max_age: '7 days'
max_entries: 30Large Application
Handle many assets with extended expiration:
pwa:
serviceworker:
workbox:
asset_cache:
enabled: true
regex: '/\.(css|js|json|xml|txt|map|ico|png|jpe?g|gif|svg|webp|bmp|woff2?)$/'
cache_name: 'production-assets'
max_age: '90 days'
max_entries: 200 # Allow many cached filesSeparate Image Cache
Cache assets but handle images separately:
pwa:
serviceworker:
workbox:
asset_cache:
enabled: true
regex: '/\.(css|js|json|xml|txt|map)$/' # No images
cache_name: 'app-assets'
max_age: '30 days'
max_entries: 50
image_cache:
enabled: true # Handle images separately with different settingsPrecaching Behavior
All matching assets are precached during service worker installation:
Installation Process
Service worker installs
Asset cache scans AssetMapper for all assets
Filters assets by regex
Downloads all matching assets
Stores in cache
Service worker activates
Impact on Install Time
Precaching all assets can increase service worker installation time. For large applications:
Optimize by:
Use stricter regex to cache fewer assets
Reduce max_entries
Consider caching only critical assets
Example: Cache only critical CSS/JS, not images:
asset_cache:
regex: '/\.(css|js)$/' # Faster install, images loaded on-demandDebugging Asset Cache
View Cached Assets
Open DevTools (F12)
Go to Application → Cache Storage
Look for "asset-cache" (or your custom cache name)
Inspect cached files and their versions
Check What Will Be Cached
To see which assets match your regex before deploying:
# List all AssetMapper assets
php bin/console debug:asset-mapper
# Filter by your regex pattern manually
php bin/console debug:asset-mapper | grep -E "\.(css|js)$"Common Issues
Assets not caching?
Verify regex pattern matches asset paths
Check AssetMapper is configured correctly
Ensure service worker is active (not waiting)
Too many assets being cached?
Make regex more specific
Reduce max_entries
Use separate caches for different asset types
Old assets not clearing?
Check max_age configuration
Verify automatic cache clearing is enabled (
clear_cache: true)
Asset Cache vs Image Cache
Both cache assets, but serve different purposes:
Purpose
Application assets (CSS, JS, etc.)
Images specifically
Strategy
CacheFirst
CacheFirst
Precaching
Yes - all matching assets
No - caches on first request
AssetMapper
Uses AssetMapper to find assets
Matches any image request
Use Case
App code and resources
User-generated or dynamic images
When to use both:
asset_cache:
regex: '/\.(css|js|json|xml)$/' # App code - precached
image_cache:
enabled: true # Images - cached on demandBest Practices
Start with defaults: Only customize if you have specific needs
Monitor cache size: Check DevTools during development
Be selective: Don't cache assets you don't need offline
Version assets: Use AssetMapper's versioning (automatic)
Test offline: Verify cached assets load without network
Separate concerns: Use image_cache for images, asset_cache for code
Set appropriate max_age: Balance freshness vs. cache hits
Troubleshooting
Service worker not installing?
Too many assets to precache
Network timeout during install
Solution: Reduce assets with stricter regex
Assets loading old versions?
AssetMapper not versioning
Cache not clearing
Solution: Ensure AssetMapper versioning is enabled
Cache growing too large?
max_entries too high
max_age too long
Solution: Reduce both values
Related Documentation
Image Caching - Dedicated image caching
Font Caching - Font-specific caching
Cache Management - Cache lifecycle
Resource Caching - Custom caching for any resource
Last updated
Was this helpful?