Resource hints¶
Resource Hints allow browsers to perform optimizations like DNS lookups, TCP connections, and resource fetching before they're actually needed. This bundle automatically generates and injects resource hints via {{ pwa() }}.
Benefits¶
- Faster page loads: Preconnect to origins before requests are made
- Reduced latency: DNS prefetch eliminates DNS lookup time
- Critical resource prioritization: Preload important resources early
- Automatic detection: Auto-detects external origins from your PWA configuration
Configuration¶
pwa:
resource_hints:
enabled: true
auto_preconnect: true # Auto-detect origins from Workbox config
preconnect:
- 'https://api.example.com'
- 'https://cdn.example.com'
dns_prefetch:
- 'https://analytics.example.com'
preload:
- href: '/fonts/custom.woff2'
as: font
type: 'font/woff2'
- href: '/css/critical.css'
as: style
fetchpriority: high
- href: '/images/hero.webp'
as: image
media: '(min-width: 768px)'
Usage¶
Resource hints are automatically injected when using {{ pwa() }}:
<!DOCTYPE html>
<html>
<head>
{{ pwa() }}
{# Resource hints are automatically included #}
</head>
</html>
To disable resource hints:
Hint types¶
Preconnect¶
Preconnect hints tell the browser to establish early connections to important origins. This includes DNS lookup, TCP handshake, and TLS negotiation.
Generated HTML:
DNS prefetch¶
DNS prefetch performs only the DNS lookup, which is less aggressive than preconnect but still helpful for origins you'll connect to later.
pwa:
resource_hints:
dns_prefetch:
- 'https://analytics.example.com'
- 'https://tracking.example.com'
Generated HTML:
Preload¶
Preload hints fetch critical resources early. Use this for resources needed for the current page.
pwa:
resource_hints:
preload:
- href: '/fonts/custom.woff2'
as: font
type: 'font/woff2'
crossorigin: anonymous
- href: '/css/critical.css'
as: style
fetchpriority: high
- href: '/images/hero.webp'
as: image
media: '(min-width: 768px)'
Preload attributes¶
| Attribute | Description | Required |
|---|---|---|
href |
URL or path to preload | Yes |
as |
Resource type: script, style, font, image, fetch |
Yes |
type |
MIME type of the resource | No |
crossorigin |
CORS setting: anonymous or use-credentials |
No (auto for fonts) |
fetchpriority |
Priority hint: high, low, or auto |
No |
media |
Media query for responsive preloading | No |
Info
Fonts always require crossorigin attribute. If not specified, the bundle automatically adds crossorigin="anonymous" for font preloads.
Asset Mapper support¶
The href attribute supports Asset Mapper logical paths. Paths without a leading / or http(s):// are automatically resolved to versioned URLs:
pwa:
resource_hints:
preload:
# Asset Mapper path - resolved to versioned URL
- href: 'fonts/inter-var.woff2'
as: font
type: 'font/woff2'
# Absolute path - kept as-is
- href: '/fonts/custom.woff2'
as: font
# External URL - kept as-is
- href: 'https://cdn.example.com/font.woff2'
as: font
| Input | Output |
|---|---|
fonts/inter.woff2 |
/assets/fonts/inter-abc123.woff2 (versioned) |
/fonts/custom.woff2 |
/fonts/custom.woff2 (unchanged) |
https://cdn.example.com/font.woff2 |
https://cdn.example.com/font.woff2 (unchanged) |
Tip
Using Asset Mapper paths ensures your preload hints always point to the correct versioned assets, even after deployments.
Auto-detection¶
When auto_preconnect is enabled (default), the bundle automatically detects external origins from your PWA configuration:
Workbox CDN¶
If you're using Workbox from CDN (use_cdn: true), preconnect hints are added for:
- https://storage.googleapis.com
- https://cdn.jsdelivr.net
Warning
use_cdn is deprecated since 1.6.0 and will be removed in 2.0.0, together with these hints: the bundled
Workbox files are served by your own server, which needs no preconnect. See
Workbox Files.
Google fonts¶
If Google Fonts caching is enabled in Workbox, preconnect hints are added for:
- https://fonts.googleapis.com
- https://fonts.gstatic.com
HTTP link headers & early hints¶
In addition to HTML link tags, the bundle automatically adds resource hints as HTTP Link headers on the response via a dedicated event listener. This enables:
- HTTP/2 Server Push (if supported by your server)
- HTTP/103 Early Hints (when combined with the Early Hints feature)
How it works¶
The ResourceHintsListener runs early in the request lifecycle (on kernel.request event) and adds all configured resource hints to the request's _links attribute. This makes them available to:
- Symfony's WebLink component for adding
Linkheaders to the response - Compatible servers (FrankenPHP, Caddy) that can send HTTP 103 Early Hints responses
HTTP 103 early hints¶
When using a server that supports Early Hints (like FrankenPHP with Caddy), the resource hints are sent to the browser before your application finishes processing the request. This allows the browser to start preconnecting, DNS prefetching, and preloading resources while waiting for the main response.
Client Server
| |
|---- GET /page --------->|
| | (starts processing)
|<--- 103 Early Hints ----| Link: <https://api.example.com>; rel=preconnect
| | Link: </fonts/inter.woff2>; rel=preload; as=font
| (browser preconnects) |
| (browser preloads) | (still processing)
| |
|<--- 200 OK -------------| (main response)
| |
Combining with early hints feature¶
For the best results, enable both Resource Hints and Early Hints:
pwa:
resource_hints:
enabled: true
preconnect:
- 'https://api.example.com'
preload:
- href: 'fonts/inter.woff2'
as: font
early_hints:
enabled: true
This ensures your resource hints benefit from HTTP 103 Early Hints when your server supports it.
Info
The ResourceHintsListener runs at priority 99, just after the EarlyHintsListener (priority 100), ensuring proper coordination between the two features.
Best practices¶
-
Don't overuse preconnect: Limit to 2-4 critical origins. Too many hints can delay more important resources.
-
Use dns-prefetch for secondary origins: For origins you'll connect to later in the page lifecycle.
-
Preload critical fonts: Fonts often block rendering, so preloading them can significantly improve perceived performance.
-
Use fetchpriority wisely: Set
highonly for above-the-fold critical resources. -
Consider media queries: Use the
mediaattribute to preload responsive images only when needed.
Example: Complete configuration¶
pwa:
resource_hints:
enabled: true
auto_preconnect: true
preconnect:
- 'https://api.myapp.com'
dns_prefetch:
- 'https://analytics.google.com'
preload:
# Critical font (Asset Mapper path - auto-versioned)
- href: 'fonts/inter-var.woff2'
as: font
type: 'font/woff2'
# Critical CSS (Asset Mapper path)
- href: 'styles/critical.css'
as: style
fetchpriority: high
# Hero image - desktop (Asset Mapper path)
- href: 'images/hero-desktop.webp'
as: image
media: '(min-width: 1024px)'
# Hero image - mobile (Asset Mapper path)
- href: 'images/hero-mobile.webp'
as: image
media: '(max-width: 1023px)'