A auditoria de Lighthouse da MAN-109 mostrou que todas as páginas públicas estouram a meta de LCP da SPEC §6.6 (≤ 2,5 s) em mobile simulado: home 4,4 s, portfólio 4,2 s, serviços 3,6 s, sobre 3,0 s e contato 2,6 s. CLS e TBT passam com folga, e acessibilidade, boas práticas e SEO marcam 100 em todas elas. Duas causas apontadas pela auditoria são corrigidas aqui. O Caddyfile não definia Cache-Control, então tudo sob /storage e /brand voltava com cacheLifetimeMs 0 e era rebaixado a cada visita — cerca de 256 KiB por page view repetido à toa. Agora /build e /storage recebem um ano imutável, o que é seguro porque ambos usam nomes que mudam junto com o conteúdo: o Vite gera hash no nome e o PublicImageUploadRules grava cada upload sob um UUID novo. /brand fica em um dia, porque esses arquivos são versionados na imagem sob nome fixo e um cache longo demais prenderia um logotipo antigo no navegador depois de uma troca de marca. O componente de logotipo também não declarava dimensões, o que a SPEC §6.4 exige para reservar espaço e evitar deslocamento de layout. Passa a declarar width/height intrínsecos dos arquivos versionados. Um logotipo enviado pelo painel tem dimensões arbitrárias e por isso não recebe atributo nenhum — melhor sem do que errado. As classes CSS continuam governando o tamanho renderizado nos dois casos. Efeito medido na home: unsized-images sai da lista de diagnósticos e uses-long-cache-ttl cai de 10 recursos para 2. Adiciona scripts/perf/lighthouse.sh com a receita da medição, incluindo o passo media:generate-variants — rodar a auditoria sem ele infla o LCP da home em cerca de 2,5 s, porque as imagens originais são servidas em tamanho cheio. Fica de fora, para PR próprio: reencodar os arquivos de marca, que hoje pesam 82 KB para renderizar em 41x40 px. Isso muda pixels no cabeçalho de todas as páginas e exige regerar os 16 baselines visuais no ambiente de paridade com o CI. Nenhum gate de performance foi adicionado ao CI. A SPEC §14.1 enumera os cinco jobs bloqueantes e a §22 define os gatilhos objetivos para adicionar capacidade; nenhum gatilho aponta para isso, e um gate criado agora nasceria vermelho. Co-Authored-By: Claude noreply@anthropic.com AI-Assisted: yes AI-Tool: claude-code Co-authored-by: manoel.neto <manoel.neto@creditas.com>
25 lines
877 B
Caddyfile
25 lines
877 B
Caddyfile
{
|
|
frankenphp
|
|
}
|
|
|
|
:8000 {
|
|
root * /app/public
|
|
encode gzip zstd
|
|
|
|
# Vite emits content-hashed filenames, so a build asset URL never changes
|
|
# meaning. Same for uploaded media: PublicImageUploadRules stores every
|
|
# upload under a fresh UUID (and ResponsiveImage derives its variants from
|
|
# that name), so replacing an image produces a new URL rather than new bytes
|
|
# at the old one. Both are safe to pin for a year.
|
|
@immutable path /build/* /storage/*
|
|
header @immutable Cache-Control "public, max-age=31536000, immutable"
|
|
|
|
# Brand assets ship inside the image under stable filenames, so a rebrand
|
|
# reuses the same URL. One day plus Caddy's ETag revalidation keeps repeat
|
|
# views cheap without pinning an outdated logo in browsers.
|
|
@brand path /brand/*
|
|
header @brand Cache-Control "public, max-age=86400"
|
|
|
|
php_server
|
|
}
|