Files
amare/resources/views/components/brand/logo.blade.php
Manoel Freitas 54cd6ba0da perf: cachear assets estáticos e reservar dimensões do logotipo (#34)
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>
2026-08-10 03:04:22 -03:00

48 lines
1.6 KiB
PHP

@props([
'variant' => 'on-light',
'mark' => false,
'alt' => null,
'class' => '',
])
@php
$settings = $siteSettings ?? null;
$uploadedPath = is_object($settings) ? ($settings->logo_path ?? null) : null;
$uploadedAlt = is_object($settings) ? ($settings->logo_alt ?? null) : null;
$resolvedAlt = $alt
?? (filled($uploadedAlt) ? $uploadedAlt : null)
?? ((is_object($settings) && filled($settings->brand_name ?? null))
? $settings->brand_name
: 'Amare Assessoria');
$variant = $variant === 'on-dark' ? 'on-dark' : 'on-light';
$kind = $mark ? 'mark' : 'lockup';
$staticSrc = asset("brand/{$kind}-{$variant}.webp");
$usesUploadedLogo = filled($uploadedPath);
$src = $usesUploadedLogo
? \Illuminate\Support\Facades\Storage::disk('public')->url($uploadedPath)
: $staticSrc;
// Reserve the box before the image arrives (SPEC §6.4). The intrinsic size
// of the shipped assets is known and fixed; an uploaded logo has arbitrary
// dimensions, so it gets no attributes rather than wrong ones. The CSS
// classes still govern the rendered size in both cases — width/height only
// give the browser the aspect ratio to reserve.
$intrinsic = $usesUploadedLogo
? []
: ($mark ? ['width' => 512, 'height' => 257] : ['width' => 512, 'height' => 495]);
@endphp
<img
{{ $attributes->merge([
'src' => $src,
'alt' => $resolvedAlt,
'class' => trim('brand-logo '.$class),
'decoding' => 'async',
'loading' => 'eager',
] + $intrinsic) }}
/>