Service-Worker-Prefetch-Budget 2025 — Prioritätsregeln und gesundes INP
Veröffentlicht: 29. Sept. 2025 · Lesezeit: 5 Min. · Von Unified Image Tools Redaktion
Viele Teams führen Bild-Prefetching zur LCP-Verbesserung ein und stellen fest, dass der Service Worker die Leitung verstopft und das INP verschlechtert. 2025 verfügen wir über stabile Priority Hints und genauere Signale der Network Information API, wodurch sich Prefetch dynamisch steuern lässt. Dieser Artikel behandelt Zielassets und Timing als „Budget“ und zeigt, wie Hero-Bilder oder Galerien vorausgeladen werden, ohne die Nutzererfahrung zu schädigen.
TL;DR
- Budget quantifizieren:
budget = (Downlink × 0,25) - laufende LCP-Ressourcen
; Prefetch pausieren, wenn das Ergebnis negativ wird. - Im Service Worker neu priorisieren: Navigation Timing + INP-Telemetrie sammeln und Rankings für den nächsten Besuch automatisch anpassen.
- Priority Hints und
fetchpriority
verbinden: HTML-Default (low
) vom Service Worker überschreiben und bei Bedarf aufauto
/high
stellen. - Background Sync für Retry: Bei Offline/Low-Bandwidth abbrechen und via
periodicSync
über Nacht neu versuchen. - Observability: Prefetch-Erfolg und ΔLCP in performance-guardian loggen, um das Budget zu überwachen.
Budgetmodell entwerfen
Metrik | Erfassung | Empfohlene Frequenz | Zweck |
---|---|---|---|
downlink | navigator.connection.downlink | Sitzungsstart & Netzwechsel | Bandbreitenabschätzung |
effectiveType | Network Information API | Jeder Lauf | 3G/4G/5G-Erkennung |
inpP75 | PerformanceObserver + RUM | Jeder Lauf | Warnung bei INP-Verschlechterung |
lcpCandidateSize | performance.getEntriesByType('largest-contentful-paint') | Wenn LCP fixiert | Größe der LCP-Ressource |
prefetchSuccessRate | Service-Worker-Logs | Täglich | Prefetch-Wirkung bewerten |
Prefetch ist situationsabhängig; diese Signale entscheiden, ob aktuell Budget existiert.
// sw/budget.ts
export function calculateBudget({ downlink, lcpSize, concurrentLoads }: {
downlink: number
lcpSize: number
concurrentLoads: number
}) {
const capacity = downlink * 125000 // Mbps -> bytes/s
const reserved = lcpSize + concurrentLoads * 150000
return Math.max(0, capacity * 0.25 - reserved)
}
Prefetch-Queue aufbauen
Kandidaten werden in prefetch-manifest.json
gepflegt.
[
{
"id": "hero-day2",
"url": "/images/event/day2@2x.avif",
"priority": 0.9,
"type": "image",
"expectedSize": 320000
},
{
"id": "gallery-mini",
"url": "/images/gallery/thumbs.webp",
"priority": 0.4,
"type": "image",
"expectedSize": 90000
}
]
Der Service Worker lädt das Manifest und reiht nur ein, was innerhalb des Budgets bleibt.
// sw/prefetch.ts
import { calculateBudget } from './budget'
import manifest from '../prefetch-manifest.json'
self.addEventListener('message', event => {
if (event.data?.type !== 'INIT_PREFETCH') return
const state = event.data.state
const budget = calculateBudget({
downlink: state.downlink,
lcpSize: state.lcpSize,
concurrentLoads: state.concurrentLoads
})
const queue = manifest
.filter(item => item.expectedSize <= budget)
.sort((a, b) => b.priority - a.priority)
prefetchQueue(queue)
})
async function prefetchQueue(queue) {
for (const entry of queue) {
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 4000)
try {
await fetch(entry.url, {
priority: entry.priority > 0.7 ? 'high' : 'low',
signal: controller.signal
})
await caches.open('prefetch-v1').then(cache => cache.add(entry.url))
logPrefetch(entry.id, true)
} catch (error) {
logPrefetch(entry.id, false, error)
} finally {
clearTimeout(timeout)
}
}
}
fetchpriority
ist noch experimentell, wird aber in Chrome/Safari unterstützt. Für Browser ohne priority
-Option einen Fallback implementieren, der das <link fetchpriority>
-Attribut anpasst.
Priority Hints mit HTML verbinden
// app/layout.tsx
export function PrefetchHints() {
return (
<>
<link
rel="preload"
as="image"
href="/images/event/day2@2x.avif"
fetchPriority="low"
/>
<script
dangerouslySetInnerHTML={{
__html: `navigator.serviceWorker?.controller?.postMessage({
type: 'INIT_PREFETCH',
state: {
downlink: navigator.connection?.downlink || 1.5,
lcpSize: window.__LCP_SIZE__ || 200000,
concurrentLoads: window.__IN_FLIGHT__ || 0
}
});`
}}
/>
</>
)
}
Cancel-Strategie zum Schutz des INP
Steigt das INP, Prefetch sofort stoppen und Prioritäten für kommende Sitzungen senken.
// sw/inp-monitor.ts
const INP_THRESHOLD = 200
new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.duration > INP_THRESHOLD) {
self.registration.active?.postMessage({ type: 'CANCEL_PREFETCH' })
updatePriority(entry.eventType)
}
}
}).observe({ type: 'event', buffered: true })
CANCEL_PREFETCH
stoppt die Queue; priority
um 0,1 zu reduzieren sorgt dafür, dass Seiten mit schweren Interaktionen Prefetch eigenständig zurückfahren.
Background Sync & nächtliches Prefetch
Erzwungenes Prefetch auf schlechten Verbindungen blockiert die UI. Mit periodicSync
erneut versuchen, sobald Wi-Fi oder Ruhezeiten anliegen.
// sw/background-sync.ts
self.addEventListener('sync', event => {
if (event.tag !== 'prefetch-sync') return
event.waitUntil(prefetchQueue(manifest))
})
async function scheduleSync() {
const registration = await self.registration.periodicSync?.register('prefetch-sync', {
minInterval: 6 * 60 * 60 * 1000
})
return registration
}
Monitoring & Analytics
Sende RUM-Events an performance-guardian, um den Nutzen zu prüfen.
sendToAnalytics('prefetch', {
budget,
downlink,
prefetchSuccessRate,
deltaLCP,
deltaINP
})
Dashboard-KPIs:
KPI | Zielwert | Alarmbedingung |
---|---|---|
ΔLCP (mit vs ohne Prefetch) | ≈ -180 ms | 3 Tage positive Werte → Alarm |
INP p75 | < 180 ms | > 200 ms → sofort stoppen |
Prefetch Success Rate | > 85% | < 70% → Manifest anpassen |
Bandbreitenanteil | < 30% | > 50% → Experiment pausieren |
Checklist
- [ ]
prefetch-manifest.json
wird gecodereviewt. - [ ] Parameter von
calculateBudget
per A/B-Test verifiziert. - [ ] Prefetch stoppt sofort bei INP-Verschlechterung.
- [ ] Background Sync versucht erneut nur bei Wi-Fi.
- [ ] performance-guardian visualisiert ΔLCP/ΔINP.
- [ ] CDN-Cache-Hitrate vor/nach Rollout verglichen.
Fazit
Ungebremstes Prefetching verschlingt Bandbreite und schadet dem INP. Mit Budgetmodell, dynamischer Priorisierung und Background Sync lässt sich Prefetch konditionieren: LCP verbessert sich, die UX bleibt geschmeidig. Kombiniere Browser-APIs mit CI-Automation, baue Kontrollschleifen und entwickle die Prefetch-Strategie je Site weiter.
Verwandte Werkzeuge
Performance Guardian
Latenzbudgets modellieren, SLO-Verstöße sichtbar machen und Nachweise für Reviews exportieren.
Compare Slider
Intuitive before/after comparison.
Bildqualitätsbudgets & CI-Gates
ΔE2000/SSIM/LPIPS-Budgets definieren, CI-Gates simulieren und Guardrails exportieren.
Audit-Logger
Maßnahmen über Bild-, Metadaten- und Nutzerlayer mit exportierbaren Audit-Trails protokollieren.
Verwandte Artikel
Loss-aware Streaming Throttling 2025 — AVIF/HEIC-Bandbreitensteuerung mit Qualitäts-SLOs
Praxisleitfaden für das Gleichgewicht zwischen Bandbreitendrosselung und Qualitäts-SLOs bei der Auslieferung hoch komprimierter Formate wie AVIF/HEIC. Enthält Kontrollmuster, Monitoring und Rollback-Strategien.
Bildoptimierung mit einem WASM-Build-Pipeline 2025 automatisieren — esbuild und Lightning CSS in der Praxis
Muster zur Automatisierung von Derivat-Erzeugung, Validierung und Signatur in einer WASM-fähigen Build-Kette. Zeigt, wie esbuild, Lightning CSS und Squoosh CLI für reproduzierbares CI/CD zusammenspielen.
Ultimative Bildkomprimierung-Strategie 2025 — Praktischer Leitfaden zur Performance-Optimierung bei Qualitätserhalt
Umfassende Aufschlüsselung der neuesten Bildkomprimierungsstrategien für Core Web Vitals und reale Betriebsumgebungen, mit spezifischen Presets, Code und Workflows nach Anwendungsfall. Umfasst JPEG/PNG/WebP/AVIF-Auswahl, Build/Delivery-Optimierung und Fehlerbehebung.
CDN Service Level Auditor 2025 — SLA-Nachweise für die Bildauslieferung
Audit-Architektur, mit der Multi-CDN-Setups ihre Bild-SLAs belegen. Behandelt Messstrategie, Beweissicherung und verhandlungsreife Reports.
Core Web Vitals Monitoring in der Praxis 2025 — SRE-Checkliste für Enterprise-Projekte
Ein praxisnahes SRE-Playbook für Enterprise-Teams, das Core Web Vitals in den täglichen Betrieb überführt – von SLO-Design über Datenerfassung bis zur Incident-Response.
Edge-Bildauslieferungs-Observability 2025 — SLO-Design und Betriebsleitfaden für Webagenturen
Beschreibt SLO-Design, Messdashboards und Alarmbetrieb, um Bildauslieferungsqualität über Edge-CDNs und Browser zu beobachten, inklusive Next.js- und GraphQL-Beispiellösungen für Webagenturen.