
⚡ Como carregar web fonts sem perder velocidade e acelerar a renderização do texto
Quando um site demora 3 segundos a carregar e depois gasta mais um segundo a redesenhar todo o texto, os visitantes vão-se embora. Não para a concorrência, simplesmente fecham o separador. O problema é quase sempre o mesmo: fontes web carregadas sem considerar o desempenho.
De acordo com os dados do HTTP Archive para 2025, cerca de 84% dos sites usam fontes web personalizadas, e o site mediano faz 5 pedidos a ficheiros de fontes, totalizando cerca de 400 KB. Numa ligação fraca, isso significa 2 a 3 segundos de bloqueio de renderização enquanto os utilizadores veem um ecrã em branco. O Google também considera o Cumulative Layout Shift causado pela troca de fontes nas Core Web Vitals.
Os quatro passos abaixo não são teoria. Este é o mínimo prático que resolve a grande maioria dos problemas de desempenho de fontes web. Cada passo demora entre 5 a 15 minutos.
💡 Visão geral rápida:
- Decida os formatos: woff2 como principal e woff como alternativa é suficiente para todos os navegadores modernos.
- Adicione preload para as fontes críticas, para que o navegador comece a descarregar imediatamente, em vez de esperar pelo CSS.
- Verifique o seu font-face: local(), ordem correta de src, unicode-range para caracteres latinos.
- Defina font-display: swap, e os visitantes veem o texto instantaneamente, mesmo enquanto a fonte ainda está a carregar.
Passo 1: Use woff2 e woff, não é necessário mais nada
Existem muitos formatos de fontes web: EOT, TTF, OTF, SVG. Mas em 2026, só precisa mesmo de dois.
woff2 é o padrão moderno. Os ficheiros são 30% mais pequenos do que woff com a mesma qualidade, porque usam compressão brotli em vez de gzip. O suporte dos navegadores inclui todos os navegadores evergreen, incluindo o Safari móvel e o Samsung Internet. Globalmente, mais de 98% dos utilizadores.
woff é a alternativa para uma pequena fração de navegadores mais antigos (Safari no iOS 11 e versões anteriores, ambientes empresariais raros). Também é comprimido e funciona em todo o lado a partir do IE9+. Mantenha-o em último lugar no src e o navegador usará woff2 se puder; caso contrário, recorrerá ao woff.
Não use EOT (Internet Explorer 8 e versões anteriores) nem TTF (formato bruto, sem compressão) em 2026. A quota desses navegadores é ruído estatístico, e cada formato extra no src aumenta o tamanho do CSS e confunde o navegador.
Se tiver ficheiros em TTF ou OTF, converta-os usando um gerador online. O Transfonter produz woff2 e woff numa só operação, mostrando uma pré-visualização dos glifos e o tamanho final do ficheiro. Uma alternativa é o Font Squirrel Webfont Generator.
Passo 2: Faça preload das fontes críticas
O navegador descobre as fontes através do CSS, e lê o CSS depois do HTML. Quando lá chega, já passaram 500 a 800 ms numa ligação média. O preload elimina este atraso: o navegador começa a descarregar a fonte assim que encontra a tag no <head>, sem esperar pelo CSS.
Tag mínima funcional:
1 <link rel="preload" as="font" 2 href="/fonts/open-sans.woff2" 3 type="font/woff2" 4 crossorigin="anonymous">
A chave é crossorigin="anonymous". Sem isto, o navegador ignora a fonte com preload e volta a descarregá-la. A razão é que as fontes são obtidas de forma anónima (CORS), mas o preload sem crossorigin faz um pedido normal. O navegador considera estes recursos diferentes e não os faz corresponder.
O que colocar em preload. Não todas as fontes do site. Apenas a usada para o texto principal acima do dobra (above the fold): cabeçalho, corpo, navegação. O resto pode esperar. Fazer preload de 4 a 5 ficheiros traz retornos decrescentes e rouba largura de banda ao conteúdo crítico.
Nota importante sobre Google Fonts e CDN. Se usar fontes do Google Fonts, os ficheiros são atualizados periodicamente, e um link de preload para uma versão antiga causará um duplo descarregamento (antiga + nova). Em vez de preload para fontes de CDN, use <link rel="preconnect"> para o domínio da fonte. Isto acelera o handshake sem risco de incompatibilidade de versões:
1 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Prefetch para fontes secundárias. rel="prefetch" diz ao navegador: «este recurso será necessário mais tarde, carrega-o quando o conteúdo principal estiver pronto.» Adequado para fontes em páginas internas ou fontes de ícones no rodapé. A prioridade é baixa, não consome largura de banda.
Um guia moderno sobre priorização de recursos está disponível na documentação do web.dev.
Passo 3: Escreva @font-face corretamente
À primeira vista, @font-face é simples. Na prática, tem quatro áreas subtis, cada uma a afetar a velocidade.
Exemplo de uma declaração correta:
1 @font-face { 2 font-family: 'Open Sans'; 3 font-weight: 400; 4 font-style: normal; 5 font-display: swap; 6 unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, 7 U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, 8 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, 9 U+FEFF, U+FFFD; 10 src: local('Open Sans'), 11 url('/fonts/open-sans.woff2') format('woff2'), 12 url('/fonts/open-sans.woff') format('woff'); 13 }
Análise por pontos:
local(): primeiro no src. Se o utilizador já tiver a fonte instalada no sistema (Roboto no Android, Segoe UI no Windows, San Francisco no macOS), o navegador usa a cópia local e descarrega zero bytes. Coloque sempre local() como a primeira linha no src. Retire o nome do próprio ficheiro da fonte: local('Open Sans') e local('Roboto Regular').
Ordem dos formatos. O navegador percorre o src da esquerda para a direita e usa o primeiro formato que entender. Portanto: local() → woff2 → woff. Nada de EOT/TTF/SVG no final, a menos que tenha um público específico com navegadores antigos, e nesse caso eles vão DEPOIS do woff (não antes).
unicode-range: carregue apenas os glifos de que precisa. Para caracteres latinos, o intervalo U+0000-00FF (Latim Básico + Suplemento Latim-1) é suficiente. São cerca de 250 glifos, contra vários milhares no conjunto completo. O tamanho real do ficheiro diminui 3 a 5 vezes. Não sobrecarregue o intervalo: cada bloco unicode extra adiciona glifos que ninguém verá. Para sites em cirílico, adicione U+0400-04FF.
Ordem dos blocos @font-face. Se tiver vários pesos (regular, negrito, itálico), coloque o peso regular (font-weight: 400) primeiro. O navegador começará a descarregar esse.
Passo 4: Ative font-display: swap e diga adeus ao FOIT
Flash of Invisible Text (FOIT) é quando o navegador esconde o texto durante 3 segundos enquanto espera pela fonte. Os utilizadores veem uma página em branco. Flash of Unstyled Text (FOUT) é quando o texto fica imediatamente visível numa fonte de sistema, sendo depois substituído pela personalizada. O segundo é sempre melhor do que o primeiro.
font-display: swap no @font-face faz exatamente isto: o texto é renderizado instantaneamente numa fonte de sistema e, quando a fonte personalizada carrega, é trocado. Ideal para texto de corpo.
Outros valores e quando usá-los:
swap: para texto de corpo. O texto fica visível imediatamente, a substituição é suave.optional: para fontes decorativas e ícones. O navegador decide se descarrega ou não a fonte. Numa ligação fraca, recusará e manterá a fonte de sistema. O período de espera é de 100 ms.block: bloqueio curto (normalmente 3 segundos), depois o texto fica visível, a fonte será trocada quando carregar. Raramente usado.fallback: um compromisso. Bloqueio curto, depois o texto fica visível, a fonte será trocada se carregar rapidamente.
Na prática, use swap para texto de corpo e optional para fontes de ícones e decoração. É suficiente.
Comportamento do navegador sem font-display. Se não especificar nada, o Chrome esconde o texto até 3 segundos, o Firefox até 3 segundos, o Safari indefinidamente e o Edge mostra a fonte de sistema imediatamente. Com font-display: swap, este comportamento torna-se unificado e o resultado é previsível.
Como verificar o resultado
Teste o seu site antes e depois em web.dev/measure. O Lighthouse mostrará «Ensure text remains visible during webfont load» como uma linha separada. Se a auditoria estiver a vermelho, o seu font-display não está a funcionar ou está em falta.
Para verificação manual: abra DevTools → Rede, defina a limitação para «Slow 3G» e atualize a página. O texto deve aparecer instantaneamente numa fonte de sistema, e não após 3 segundos de ecrã em branco.
As capturas de ecrã abaixo mostram a diferença entre a abordagem padrão e a otimizada (teste em Slow 3G):

Padrão: o texto fica oculto até a fonte carregar

Comportamento otimizado: o texto fica visível imediatamente numa fonte de sistema
A diferença é visível a olho nu: a primeira captura de ecrã mostra um ecrã branco, a segunda mostra o conteúdo disponível instantaneamente.
Na conferência performance.now() 2024, Mandy Michael aborda estratégias avançadas: unicode-range incremental, fatiamento de fontes e trabalho com fontes variáveis. Para quem quiser ir além dos quatro passos básicos.
⁉️🤔 Perguntas frequentes
Porque preciso de woff se o woff2 é suportado em todo o lado?
Os restantes utilizadores de Safari iOS antigo (iOS 11 e versões anteriores) e ambientes empresariais raros com navegadores bloqueados não suportam woff2. Sem uma alternativa woff, estes utilizadores verão uma fonte de sistema em vez da sua. O woff adiciona 15 a 20 KB ao conjunto: um preço insignificante para cobrir a quota restante.
Posso simplesmente usar o Google Fonts e não me preocupar?
Sim, e para a maioria dos sites este é o caminho ideal. O Google Fonts serve automaticamente woff2 para navegadores modernos, usa uma CDN geodistribuída e suporta
display=swapcomo parâmetro de URL. Desvantagens: dependência de uma CDN externa (considerações de privacidade, RGPD), incapacidade de controlarunicode-rangee a instalação de fontes locais. Se a privacidade e o controlo forem importantes, aloje as fontes você mesmo.
Como sei se as fontes estão realmente a tornar o meu site mais lento?
O Lighthouse (o separador Auditorias nas Chrome DevTools) mostrará a auditoria «Ensure text remains visible during webfont load». O WebPageTest fornece um gráfico em cascata com o tempo de cada pedido de fonte. Se as fontes começarem depois do primeiro CSS, o preload não está configurado. Se a mudança de layout for superior a 0,1, a fonte está a causar Cumulative Layout Shift, e o Google conta isto nas Core Web Vitals.
font-display: swap estraga o design, o texto «salta» na troca?
Sim, esta é uma desvantagem conhecida do swap. Combata-a com duas técnicas. Primeiro: defina
font-sizeeline-heightpara o texto de forma a corresponderem à fonte de sistema alternativa. A diferença nas métricas será mínima. Segundo: use o Font Style Matcher ou a propriedadesize-adjustno@font-face(disponível em navegadores modernos) para fazer corresponder as métricas da fonte personalizada às da fonte de sistema. Após o ajuste, o CLS será zero.
Devo fazer preload de todas as fontes do site?
Não. Faça preload apenas das fontes críticas: as que compõem o texto acima do dobra (os primeiros 1 a 2 ecrãs). Carregue o resto normalmente através do CSS. Fazer preload de mais de 5 fontes congestiona a largura de banda e atrasa recursos mais importantes na fila. Na prática, 1 a 2 links de preload cobrem a grande maioria dos cenários.
Vale a pena o esforço: quatro passos, quatro minutos
Configurar fontes web não é um projeto de uma semana. Converter para woff2, corrigir o @font-face, o preload e o font-display: swap demora 20 a 30 minutos de trabalho, mesmo que nunca o tenha feito antes.
O benefício é mensurável: o texto fica visível 1,5 a 2,5 segundos mais cedo em Slow 3G. As Core Web Vitals não penalizam pela mudança de layout. E os utilizadores não se vão embora a olhar para um ecrã branco.
Comece com uma fonte: a fonte principal do texto de corpo. Siga os quatro passos. Verifique o Lighthouse antes e depois. A diferença nos números será mais convincente do que qualquer argumento.



