Fonte própria sem travar o carregamento

11 de agosto de 2026 9 min de leitura Por João Gabriel

Fonte é o recurso que o navegador descobre mais tarde e precisa mais cedo. Essa contradição explica o texto que demora a aparecer, o texto que aparece e depois muda de forma, e boa parte do LCP ruim em páginas que só têm texto no topo.

O problema é a ordem, não o tamanho

Um arquivo de fonte moderno em WOFF2 é pequeno. O problema nunca foi o peso. É quando o navegador descobre que precisa dele.

A cadeia normal é esta: o navegador baixa o HTML, encontra o CSS, baixa o CSS, processa o CSS, descobre a regra @font-face, verifica quais caracteres a página usa, e só então começa a baixar a fonte. São quatro passos em série antes do primeiro byte da fonte sair do servidor.

Enquanto isso, o texto já poderia estar na tela. Se a página tem um título grande no topo, esse título costuma ser o elemento que define o LCP. Uma fonte que chega atrasada pode atrasar a métrica inteira, mesmo com todo o resto pronto. O contexto completo dessa métrica está em o guia de Core Web Vitals.

A fonte é o recurso que o navegador descobre por último e precisa primeiro. Todo o resto deste artigo é sobre desfazer essa inversão.

O custo real de puxar a fonte de um CDN de terceiro

A forma mais comum de usar uma fonte é colar uma linha que aponta para o servidor de quem distribui a fonte. Funciona, é fácil, e adiciona uma conta que não aparece:

  • Um domínio novo custa uma negociação inteira. Consulta de DNS, conexão e handshake de segurança acontecem antes de qualquer byte útil. Isso vale por origem, não por arquivo.
  • Normalmente são duas origens, não uma. No arranjo mais popular, o CSS vem de um domínio e o arquivo da fonte vem de outro. São duas negociações em cadeia, e a segunda só começa depois da primeira terminar.
  • Você entrou numa fila que não controla. Se o serviço estiver lento, a sua página fica lenta junto, e não existe nada que você possa fazer naquele momento.
  • Aumenta a cadeia de dependência crítica. Cada elo em série é um ponto onde a renderização do texto pode parar.

O argumento do cache compartilhado morreu

A justificativa clássica para usar CDN de fonte era esta: se muitos sites usam a mesma fonte do mesmo endereço, o visitante já teria o arquivo em cache de outro site e não baixaria nada.

Isso deixou de ser verdade. Os navegadores passaram a particionar o cache HTTP por site, justamente para impedir que um site descubra o histórico de navegação do usuário medindo o que já está em cache. O Safari faz isso há muitos anos, e Chrome e Firefox passaram a fazer no começo desta década.

Na prática: o arquivo baixado no site A não é reaproveitado no site B, mesmo sendo exatamente a mesma URL. Todo visitante seu baixa a fonte do zero, agora com o custo extra de conversar com um domínio estranho. O benefício sumiu e o custo ficou.

Hospedar a fonte no próprio domínio

A alternativa é baixar os arquivos e servi-los do mesmo endereço da sua página. É o que este site faz: Inter e JetBrains Mono vivem em /fonts aqui mesmo, não vêm de lugar nenhum.

O que isso resolve, em ordem de importância:

  1. Zero conexão nova. A conexão com o seu domínio já está aberta desde o HTML. A fonte entra por ela.
  2. Cadeia mais curta. Some o passo de baixar um CSS de terceiro só para descobrir onde a fonte está.
  3. Controle de cache. Você define o cabeçalho de cache. Arquivo de fonte com nome versionado pode ser cacheado por um ano com segurança.
  4. Você pode fazer preload. Este é o ponto decisivo, e ele só existe quando você sabe a URL final do arquivo. Com CDN de terceiro, a URL do arquivo está escondida dentro de um CSS que você ainda não baixou.

Use sempre WOFF2. Ele é o formato comprimido moderno, tem suporte universal nos navegadores atuais e dispensa a lista de formatos alternativos que ainda circula em tutoriais antigos. Servir TTF ou OTF direto na web é desperdício puro de banda.

preload: antecipar a descoberta

O preload resolve o problema de ordem descrito lá no começo. Ele diz ao navegador, ainda na leitura do HTML, que aquele arquivo vai ser necessário. O download começa em paralelo com o CSS, em vez de esperar por ele.

É uma linha no head, e ela tem uma armadilha que anula tudo se for esquecida:

Não pré-carregue tudo

O preload não cria banda, ele reordena a fila. Cada arquivo que você antecipa disputa com a imagem do topo, que costuma ser o elemento de LCP. Pré-carregar seis fontes é uma forma eficiente de atrasar tudo.

O critério é estreito: pré-carregue apenas as fontes que aparecem na primeira tela, no peso e no estilo em que aparecem. Aqui neste site são duas, uma de cada família, e apenas o subset latino. O resto o CSS busca no tempo normal dele.

font-display: escolher entre texto invisível e texto que pula

Enquanto a fonte não chega, o navegador precisa decidir o que fazer com o texto. Existem duas escolhas ruins e você tem que ficar com uma: mostrar nada, ou mostrar com outra fonte e trocar depois. A propriedade font-display é onde você declara qual prefere.

ValorO que aconteceEfeito colateral
blockTexto invisível por cerca de 3 segundos, depois trocaÉ o texto invisível clássico. Atrasa o LCP quando o topo é texto.
swapTexto imediato com a fonte de sistema, troca assim que a sua chegarNada fica invisível. Risco de o texto mudar de forma e empurrar o layout.
fallbackJanela curta de invisibilidade, depois fallback, e a troca só vale por poucos segundosMeio-termo. Em rede ruim, a sua fonte simplesmente não é usada.
optionalJanela curta e sem troca: ou a fonte chegou a tempo, ou não é usada nesta visitaZero risco de deslocamento. O visitante pode ver a página inteira sem a sua fonte.

O padrão do navegador quando você não declara nada equivale ao comportamento de bloqueio. Ou seja: não declarar é escolher o pior caso para LCP.

Para uma landing page, swap costuma ser a escolha certa e é a que este site usa. O raciocínio: texto legível imediatamente vale mais que consistência tipográfica nos primeiros instantes, e quem entrou na página quer ler, não admirar a fonte. Quem prioriza estabilidade absoluta de layout acima de identidade visual tem em optional um argumento legítimo.

O texto que pula na troca, e como reduzir isso

O preço do swap é que a fonte de fallback e a sua fonte quase nunca ocupam o mesmo espaço. Larguras de caractere e altura de linha diferem, então o texto reflui no momento da troca. Se isso empurra o conteúdo abaixo, você acabou de gerar deslocamento de layout.

O controle existe e é pouco usado. No @font-face da fonte de fallback dá para declarar size-adjust, ascent-override e descent-override, ajustando a fonte de sistema para ocupar aproximadamente o mesmo espaço da sua. A troca continua acontecendo, mas quase não empurra nada.

Duas medidas mais simples ajudam antes disso: escolher uma fonte de fallback com métricas parecidas com a sua, e evitar declarar altura de linha em unidades que dependam do tamanho do glifo. Boa parte do pulo visível vem de espaçamento calculado a partir da fonte, não da fonte em si.

Subsetting: baixar só os caracteres que a página usa

Uma fonte completa carrega alfabeto cirílico, grego, vietnamita e um punhado de símbolos que a sua página em português nunca vai mostrar. Subsetting é cortar isso.

O mecanismo elegante é o unicode-range: você declara vários @font-face para a mesma família, cada um apontando para um arquivo com uma faixa de caracteres. O navegador olha o que a página realmente usa e baixa só os arquivos necessários. Se nenhum caractere daquela faixa aparece, o arquivo nunca é requisitado.

É assim que este site está montado: cada família tem um arquivo para o subset latino e outro para o latino estendido, separados por unicode-range.

Existe uma modalidade mais agressiva, que é gerar um arquivo contendo exatamente os caracteres de um texto fixo. Serve para logotipo e para título único. Não serve para conteúdo que muda, porque qualquer caractere fora do subset simplesmente não é desenhado com a sua fonte.

A decisão que rende mais que todas as anteriores

Toda a técnica deste artigo perde para uma escolha de projeto: quantas fontes a página carrega.

Cada família é um conjunto novo de arquivos. Cada peso é potencialmente mais um arquivo. Cada estilo itálico, mais um. Uma página com duas famílias, quatro pesos e itálico pode acabar com uma dúzia de arquivos, e nenhuma otimização compensa isso.

  • Duas famílias no máximo. Uma para texto e, se houver motivo real, uma segunda para um papel específico.
  • Prefira fonte variável. Um único arquivo cobrindo uma faixa de pesos costuma pesar menos que três arquivos estáticos.
  • Não carregue itálico se você não usa itálico. É a fonte fantasma mais comum, herdada de configuração padrão de tema.
  • Considere a pilha do sistema. Para muito conteúdo, usar a fonte nativa do aparelho é uma decisão defensável: zero requisição, zero espera, zero deslocamento.

Uma nota de honestidade sobre resultado: eu não vou te dar um número de quantos milissegundos essas medidas economizam, porque esse número depende da sua rede, do seu aparelho, do seu servidor e do seu layout. Qualquer valor específico apresentado como universal aqui seria invenção. Meça a sua página antes e depois, com a página real e com limitação de rede ligada, e o seu número vai valer mais que qualquer média publicada.

Perguntas frequentes

Devo hospedar a fonte no meu servidor ou usar o CDN?

Hospedar no próprio domínio é melhor na maior parte dos casos. Você elimina uma consulta de DNS e um handshake com origem externa, encurta a cadeia de dependências, controla o cache e passa a poder fazer preload, o que é impossível quando a URL do arquivo está escondida dentro de um CSS de terceiro. O antigo argumento do cache compartilhado deixou de valer quando os navegadores passaram a particionar o cache HTTP por site.

Qual valor de font-display eu devo usar?

Para landing page, swap costuma ser a melhor escolha: o texto aparece imediatamente com a fonte do sistema e troca quando a sua chega. Você troca invisibilidade por um possível reflow, e o reflow pode ser reduzido ajustando as métricas da fonte de fallback. Se estabilidade absoluta de layout for mais importante que a identidade tipográfica, optional elimina o deslocamento ao custo de a sua fonte não aparecer em conexões ruins. Não declarar nada é o pior caso, porque o padrão bloqueia o texto.

Preciso fazer preload de todas as minhas fontes?

Não, e fazer isso costuma piorar. O preload reordena a fila de downloads, não aumenta a banda disponível, então cada fonte antecipada disputa com a imagem do topo. Pré-carregue apenas as fontes visíveis na primeira tela, no peso em que aparecem. E lembre do atributo crossorigin: sem ele, a fonte é baixada duas vezes.

Por que meu texto fica invisível por alguns segundos?

É o comportamento padrão do navegador quando font-display não foi declarado. Ele esconde o texto por cerca de três segundos esperando a fonte chegar, e só depois desenha com a fonte de sistema. Declarar font-display swap resolve imediatamente: o texto passa a aparecer desde o início.

Fonte variável vale a pena?

Vale quando você usa mais de dois pesos da mesma família. Um único arquivo variável cobrindo a faixa de pesos costuma pesar menos que os arquivos estáticos equivalentes, e evita requisições separadas. Se você usa apenas um peso, um arquivo estático daquele peso específico pode ser menor. A decisão depende de quantos pesos o seu design realmente exige.