Orçamento de prefetch de imagens no Service Worker 2025 — Prioridades inteligentes mantendo o INP saudável
Publicado: 29 de set. de 2025 · Tempo de leitura: 5 min · Pela equipe editorial da Unified Image Tools
Equipes adicionam prefetch de imagens para ganhar LCP, mas o Service Worker pode consumir banda e piorar o INP. Em 2025 temos Priority Hints estável e sinais melhores do Network Information API, permitindo tratar o prefetch como um “orçamento” dinâmico. Este artigo mostra como antecipar hero ou galeria sem comprometer a experiência.
TL;DR
- Quantifique o orçamento:
budget = (downlink × 0,25) - ativo LCP atual
; se ficar negativo, pare o prefetch. - Reordene no Service Worker: colete telemetria de Navigation Timing + INP e ajuste prioridades para a próxima visita.
- Sincronize Priority Hints e
fetchpriority
: deixelow
no HTML, mas promova paraauto
/high
no Service Worker conforme as condições. - Re-tente com Background Sync: cancele em offline/banda baixa e reagende via
periodicSync
quando houver Wi-Fi. - Observabilidade: registre acertos e ΔLCP no performance-guardian para validar o orçamento.
Modelando o orçamento
Métrica | Como obter | Frequência | Objetivo |
---|---|---|---|
downlink | navigator.connection.downlink | Início + mudança de rede | Estimativa de banda |
effectiveType | Network Information API | Toda execução | Classificar 3G/4G/5G |
inpP75 | PerformanceObserver + RUM | Toda execução | Alertar degradação de INP |
lcpCandidateSize | performance.getEntriesByType('largest-contentful-paint') | Quando LCP finaliza | Medir o ativo LCP |
prefetchSuccessRate | Logs do Service Worker | Diário | Avaliar eficácia do prefetch |
Use esses sinais para decidir se vale antecipar ativos agora.
// 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)
}
Construindo a fila de prefetch
Liste os candidatos em prefetch-manifest.json
.
[
{
"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
}
]
O Service Worker lê o manifest e só enfileira itens que cabem no orçamento.
// 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
ainda não é universal; se o navegador ignorar, reescreva <link fetchpriority>
no HTML.
Sincronizando Priority Hints com o HTML
// 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
}
});`
}}
/>
</>
)
}
Estratégias de cancelamento para proteger o INP
Quando o INP piorar, cancele imediatamente e reduza a prioridade para sessões futuras.
// 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 })
Cada ocorrência reduz a prioridade em 0,1, fazendo com que páginas com interações pesadas limitem o prefetch automaticamente.
Background Sync e prefetch noturno
Prefetch em banda ruim causa travamentos. Use periodicSync
para tentar novamente quando houver melhores condições.
// 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
}
Monitoramento e analytics
Envie eventos para performance-guardian.
sendToAnalytics('prefetch', {
budget,
downlink,
prefetchSuccessRate,
deltaLCP,
deltaINP
})
KPI sugeridos:
KPI | Meta | Condição de alerta |
---|---|---|
ΔLCP (prefetch vs sem prefetch) | ≈ -180 ms | Positivo por 3 dias → revisar |
INP p75 | < 180 ms | > 200 ms → parar imediatamente |
Prefetch Success Rate | > 85% | < 70% → ajustar manifest |
Uso de banda | < 30% | > 50% → pausar experimento |
Checklist
- [ ]
prefetch-manifest.json
revisado por pares. - [ ] Parâmetros de
calculateBudget
validados em teste A/B. - [ ] Prefetch cancela assim que o INP piora.
- [ ] Background Sync roda apenas em Wi-Fi.
- [ ] ΔLCP/ΔINP disponível no performance-guardian.
- [ ] Taxa de acerto de cache CDN comparada antes/depois do rollout.
Resumo
Prefetch sem controle desperdiça banda e fere o INP. Com orçamento dinâmico, prioridades ajustáveis e Background Sync, você torna o prefetch condicional: LCP melhora enquanto o usuário continua com uma experiência suave. Combine APIs do navegador com automação de CI para construir um ciclo de controle e evoluir a estratégia de prefetch conforme o perfil do seu site.
Ferramentas relacionadas
tools.performanceGuardian
toolDescriptions.performanceGuardian
Comparador
Comparação antes/depois intuitiva.
Orçamentos de qualidade de imagem e gates de CI
Modele orçamentos de ΔE2000/SSIM/LPIPS, simule gates de CI e exporte guardrails.
Registrador de auditoria
Registre eventos de remediação nos layers de imagem, metadados e usuário com trilhas de auditoria exportáveis.
Artigos relacionados
Throttling de streaming consciente da perda 2025 — Controlando banda AVIF/HEIC com SLOs de qualidade
Guia prático para equilibrar limitação de banda e SLOs de qualidade ao entregar formatos de alta compressão como AVIF/HEIC. Inclui padrões de controle de streaming, monitoramento e estratégia de rollback.
Automatizando a otimização de imagens com um pipeline WASM 2025 — Integrando esbuild e Lightning CSS
Padrões para automatizar a geração, validação e assinatura de derivados de imagem com uma cadeia de build habilitada para WASM. Mostra como unir esbuild, Lightning CSS e Squoosh CLI para obter um CI/CD reproduzível.
Estratégia Definitiva de Compressão de Imagem 2025 — Guia Prático para Otimizar Velocidade Percebida Preservando Qualidade
Análise abrangente das estratégias mais recentes de compressão de imagem para Core Web Vitals e operações do mundo real, com presets específicos, código e fluxos de trabalho por caso de uso. Cobre seleção JPEG/PNG/WebP/AVIF, otimização de build/entrega e solução de problemas.
Auditor de SLA para CDN 2025 — Monitoramento baseado em evidências para entrega de imagens
Arquitetura de auditoria que comprova o cumprimento de SLA de imagens em ambientes multi-CDN. Cobre estratégia de medição, coleta de evidências e relatórios prontos para negociação.
Monitoramento prático de Core Web Vitals 2025 — Checklist SRE para projetos enterprise
Playbook com visão de SRE que ajuda equipes de produção web enterprise a operacionalizar Core Web Vitals, cobrindo design de SLO, coleta de dados e resposta a incidentes ponta a ponta.
Observabilidade da entrega de imagens Edge 2025 — Guia de design SLO e operações para agências web
Explica o design de SLO, dashboards de medição e operação de alertas para monitorar a qualidade de entrega de imagens em CDNs Edge e navegadores, com exemplos em Next.js e GraphQL pensados para agências web.