Otimização de fontes web com Claude Code
Guia prático para otimizar fontes web com Claude Code: preload, font-display, subsetting, CLS/LCP e validação.
Fonte web lenta vira problema de renderização
Fontes web melhoram identidade visual, mas também podem prejudicar performance. Quando uma fonte chega tarde, o texto pode ficar invisível por alguns instantes, um título pode mudar de largura, um botão de conversão pode pular e o LCP pode piorar. LCP, Largest Contentful Paint, mede quando o maior conteúdo visível no primeiro viewport aparece. CLS, Cumulative Layout Shift, mede deslocamentos inesperados de layout.
Em idiomas com muitos caracteres, como japonês, chinês e coreano, o risco é maior. Um único arquivo de fonte pode ser mais pesado do que todo o CSS crítico. Por isso Claude Code precisa de uma tarefa bem definida. “Otimize as fontes” é amplo demais. A instrução correta diz quais fontes são críticas, quais textos podem usar fontes do sistema, quando usar preload, como evitar CLS e como verificar o resultado.
Este guia usa Astro como exemplo. Vamos cobrir estratégia de carregamento, preload, preconnect, font-display, fontes variáveis, subsetting, self-host versus terceiros, riscos de CLS/LCP, checagens no estilo Lighthouse e WebPageTest, e prompts seguros para Claude Code. Para comportamento do navegador, use a documentação oficial da MDN sobrefont-display erel="preload". Para visão geral, veja web.dev sobreboas práticas de fontes, otimização de web fonts eWeb Vitals.
Defina a estratégia antes de editar
A primeira pergunta é: qual texto precisa aparecer no primeiro viewport com a fonte de marca? Se a resposta for “tudo”, o site provavelmente vai desperdiçar banda. Em blogs, o corpo pode começar com fonte do sistema e usar a fonte web apenas em títulos. Em SaaS, uma fonte variável latina pode unificar rótulos, botões, tabelas e números. Em landing pages, a fonte do título compete com a imagem hero pelo orçamento de LCP.
| Caso de uso | Estratégia | Benefício | Erro comum |
|---|---|---|---|
| Blog multilíngue | Corpo com fonte do sistema, títulos com subset web font | Conteúdo fica legível imediatamente | Fonte decorativa aplicada ao corpo inteiro |
| Dashboard SaaS | Fonte variável self-host para UI | Um arquivo cobre vários pesos | Incluir itálico, eixos ou idiomas não usados |
| Hero de landing page | Preload só do WOFF2 usado no título LCP | Mensagem principal aparece cedo | Preload de todos os pesos |
| Icon font antiga | Migrar para SVG ou biblioteca de ícones | Remove uma requisição de fonte | Quebrar CSS com pseudo-elementos |
Para páginas de conteúdo, priorize leitura. Para interfaces de produto, priorize consistência de UI. Para páginas de venda, avalie fonte e imagem juntas. A estratégia de imagem está naotimização de imagens com Claude Code, e a visão mais ampla está emotimização de performance com Claude Code.
Implementando preload e preconnect no Astro
preload é uma dica forte para o navegador. Use apenas para um ou dois arquivos WOFF2 realmente usados no primeiro viewport. Não faça preload de todos os pesos, todos os idiomas ou fontes que aparecem só depois da rolagem. Se as fontes são self-host no mesmo domínio, normalmente não é preciso preconnect. Se você usa Google Fonts ou outro provedor, preconnect pode reduzir custo de conexão para o domínio CSS e o domínio das fontes.
---
// src/layouts/BaseLayout.astro
const criticalFonts = [
{ href: "/fonts/inter-var-latin.woff2", type: "font/woff2" },
{ href: "/fonts/noto-sans-jp-latin-kana.woff2", type: "font/woff2" },
];
const usesGoogleFonts = false;
---
<html lang="pt">
<head>
{criticalFonts.map((font) => (
<link rel="preload" href={font.href} as="font" type={font.type} crossorigin />
))}
{usesGoogleFonts && <link rel="preconnect" href="https://fonts.googleapis.com" />}
{usesGoogleFonts && <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />}
<link rel="stylesheet" href="/styles/fonts.css" />
</head>
<body>
<slot />
</body>
</html>
Depois da implementação, revise o HTML gerado. O href do preload precisa bater com o src em @font-face. A tag precisa de as="font", type="font/woff2" e crossorigin. A fonte precargada precisa ser usada no primeiro viewport. Se o navegador avisar que um preload não foi usado, remova esse hint.
Use font-display sem criar CLS
font-display: swap mostra primeiro uma fonte fallback e troca para a fonte web quando ela chega. Isso evita texto invisível, mas pode mover o layout se fallback e fonte final tiverem métricas diferentes. Para texto não crítico em rede lenta, optional pode ser melhor, pois o navegador pode manter o fallback.
/* public/styles/fonts.css */
@font-face {
font-family: "InterVariable";
src: url("/fonts/inter-var-latin.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "NotoSansJPSubset";
src: url("/fonts/noto-sans-jp-latin-kana.woff2") format("woff2");
font-weight: 400 700;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+3000-30FF, U+FF00-FFEF;
}
@font-face {
font-family: "InterFallback";
src: local("Arial");
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
:root {
--font-ui: "InterVariable", "InterFallback", system-ui, sans-serif;
--font-ja: "NotoSansJPSubset", "Hiragino Sans", "Yu Gothic", sans-serif;
}
body {
font-family: var(--font-ui);
}
article {
font-family: var(--font-ja);
}
O descriptorunicode-range faz uma face de fonte valer apenas para certos caracteres. Isso não diminui o arquivo sozinho. Para reduzir bytes, você precisa gerar um WOFF2 menor.
Reduza bytes com fontes variáveis e subsetting
Fontes variáveis substituem vários arquivos estáticos quando a UI usa muitos pesos. Ainda assim, elas não são automaticamente menores. Se incluem muitos eixos, itálico e muitos idiomas, podem continuar pesadas. Peça para Claude Code auditar pesos, famílias e CSS antes de migrar.
Subsetting cria uma fonte com apenas os caracteres necessários. Funciona bem para navegação, títulos hero, rótulos fixos e CTAs. É mais arriscado para corpo de artigo, porque cada novo texto pode trazer caracteres que ficaram fora do subset.
# Create a WOFF2 subset with Latin, punctuation, kana, and full-width forms.
python -m pip install "fonttools[woff]"
mkdir -p public/fonts
pyftsubset ./vendor-fonts/NotoSansJP-Regular.ttf \
--output-file=./public/fonts/noto-sans-jp-latin-kana.woff2 \
--flavor=woff2 \
--layout-features='*' \
--unicodes="U+0000-00FF,U+3000-30FF,U+FF00-FFEF"
Esse exemplo não inclui a maioria dos kanji. É adequado para menu, título ou texto fixo, mas não para um artigo japonês completo. Para corpo de texto, extraia caracteres reais dos MDX e use --text-file, ou gere um subset separado. Verifique também a licença antes de self-host, modificar ou redistribuir.
Self-host ou provedor externo
Self-host dá controle de URL, cache, fingerprint, preload e subsetting. Em troca, você mantém arquivos, licença, atualizações e scripts. Um provedor externo é mais rápido para começar, mas adiciona conexões externas e uma requisição CSS antes da fonte.
| Critério | Self-host | Terceiro |
|---|---|---|
| Conexão | Mesmo domínio | DNS, TLS, CSS externo e fonte externa |
| Cache | Controlado por você | Controlado pelo provedor |
| Preload | Arquivo WOFF2 exato | URL pode vir do CSS do provedor |
| Subsetting | Livre | Depende do serviço |
| Operação | Mais responsabilidade | Mais simples, mais dependência |
Em páginas sensíveis a conversão, self-host de fontes críticas costuma ser melhor. Fontes decorativas podem ser carregadas depois. Se usar terceiro, carregue apenas pesos usados, adicione display=swap e não mantenha CSS duplicado após migrar para self-host.
Verifique com Lighthouse e waterfall estilo WebPageTest
Depois de implementar, olhe a ordem da rede. Lighthouse dá sinal de laboratório para LCP, CLS e auditorias de fontes. Depois revise uma waterfall como no WebPageTest: HTML, CSS, fonte crítica, imagem hero e JavaScript. A fonte crítica deve começar cedo sem bloquear CSS nem atrasar o elemento LCP.
URL="https://example.com/"
npx --yes lighthouse "$URL" \
--only-categories=performance \
--chrome-flags="--headless" \
--output=json \
--output-path=./lighthouse-fonts.json
node -e "const r=require('./lighthouse-fonts.json'); for (const id of ['largest-contentful-paint','cumulative-layout-shift','font-display']) console.log(id, r.audits[id]?.displayValue ?? r.audits[id]?.score ?? 'n/a')"
Sinais bons: um ou dois WOFF2 críticos começam cedo; não há aviso de preload não usado; visita repetida usa cache; título e CTA não se movem durante o swap; não resta CSS do Google Fonts após self-host; o mesmo arquivo não é baixado duas vezes.
Falhas comuns: preload de bold que não aparece no primeiro viewport; subset sem pontuação ou dígitos full-width; font-display: swap sem ajuste de fallback; icon font ainda carregada depois da migração para SVG; fonte de provedor externo junto com fonte local da mesma família.
Prompts seguros para Claude Code
Separe auditoria, implementação e validação. Comece sem edição.
Audit web font loading in this Astro site. Do not edit files yet.
Find:
- @font-face, Google Fonts, Fontsource, and CSS import locations
- Font files used above the fold
- preload and preconnect hints that are missing or unnecessary
- CLS or LCP risks caused by font swapping
- Candidates for self-hosting, variable fonts, and subsetting
Return:
- A prioritized table of changes
- Files that should be edited and files that must not be touched
- Verification commands and residual risks
Depois limite a implementação.
Implement web font optimization only in these files:
- src/layouts/BaseLayout.astro
- public/styles/fonts.css
- generated files under public/fonts/
Acceptance criteria:
- Preload only WOFF2 files used in the first viewport
- Do not add preconnect when fonts are self-hosted
- Every @font-face has a deliberate font-display value
- Fallback metrics are adjusted to reduce CLS
- Existing routes, article slugs, hero images, and unrelated content are untouched
Verification:
- npm run build
- node scripts/check-code-fences.mjs
- Lighthouse check for LCP, CLS, and font-display
- Report what could not be verified
Resultado prático e CTA
No fluxo do Masa, a instrução específica funcionou melhor do que a genérica. “Faça preload apenas da fonte usada no título LCP, mantenha o corpo legível com fontes do sistema e reporte risco de CLS” gerou diffs menores. Em uma página japonesa, um subset latino e kana deixou o primeiro viewport mais estável, mas cobertura completa do corpo exigiu extração de caracteres. A verificação mais útil foi waterfall móvel lenta junto com revisão manual do título e do CTA.
Para levar isso a uma equipe, coloque as regras no CLAUDE.md. Comece pelocheat sheet gratuito para comandos seguros, use ostemplates de produtos para prompts repetíveis e considere otreinamento Claude Code se quiser melhorar Core Web Vitals, qualidade de artigos e CTA de monetização ao mesmo tempo.
Autochecagem antes de publicar: o artigo contém mais de três casos de uso, exemplos Astro/CSS/bash copiáveis, links oficiais para MDN e web.dev, links internos, falhas concretas, CTA natural e nota de verificação prática.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Permission receipt no Claude Code: escopo, prova e rollback
Padrão de permission receipt para Claude Code: ações permitidas, limites de aprovação, comandos de prova, rollback e CTA de receita.
Agent Harness seguro para Claude Code e Codex: permissoes, verificacao e rollback
Monte uma base segura para agentes com Claude Code e Codex usando politicas, plano, verificacao e recuperacao.
Subagentes no Claude Code: guia prático para delegar trabalho com segurança
Guia prático de subagentes no Claude Code para dividir artigos e código: regras, prompts, riscos e checklist.