Reduzir o tamanho da fonte na Web

A tipografia é fundamental para proporcionar design, uso de marca, legibilidade e acessibilidade de boa qualidade. Além de oferecer tudo isso, as webfonts permitem selecionar, pesquisar, alterar o zoom e facilitar o uso de alto DPI em textos, proporcionando uma renderização de texto consistente e nítida, independentemente do tamanho e da resolução da tela. As fontes da Web são essenciais para oferecer design, experiência de usuário (UX) e desempenho de qualidade.

A otimização de fontes da Web é um fator crítico da estratégia geral de performance. Cada fonte é um recurso adicional, e algumas fontes podem bloquear a renderização do texto. No entanto, o uso de fontes da Web na página não significa que a renderização será necessariamente mais lenta. Pelo contrário, fontes otimizadas, combinadas com uma estratégia sensata para a forma como elas são carregadas e aplicadas na página, podem ajudar a reduzir o tamanho total e o tempo de renderização.

Anatomia de uma fonte da Web

Uma fonte da Web é uma coleção de glifos. Cada glifo é uma forma vetorial que descreve uma letra ou símbolo. Como resultado, duas variáveis simples determinam o tamanho de um arquivo de fonte específico: a complexidade dos caminhos vetoriais de cada glifo e o número de glifos em cada fonte. Por exemplo, a Open Sans, uma das fontes da Web mais comuns, contém 897 glifos, que incluem caracteres latinos, gregos e cirílicos.

Tabela de glifos da fonte

Ao escolher uma fonte, é importante considerar quais conjuntos de caracteres são aceitos. Se você precisar localizar o conteúdo da página para vários idiomas, use uma fonte que possa oferecer aparência e experiência consistentes aos usuários. Por exemplo, a família de fontes Noto do Google pretende ser compatível com todos os idiomas do mundo. Observe, contudo, que o tamanho total do Noto, com todos os idiomas incluídos, resulta em um download de ZIP com mais de 1,1 GB.

Neste post, você vai descobrir como reduzir o tamanho do arquivo das fontes da Web.

Formatos de fontes da Web

Atualmente, há dois formatos de contêiner de fontes recomendados em uso na Web:

O WOFF e o WOFF 2.0 têm amplo suporte e são compatíveis com todos os navegadores modernos.

  • Sirva a variante WOFF 2.0 para navegadores modernos.
  • Se for absolutamente necessário, por exemplo, se você ainda precisar oferecer suporte ao Internet Explorer 11, use o WOFF como substituto.
  • Como alternativa, considere não usar fontes da Web para navegadores legados e usar as fontes do sistema. Isso também pode melhorar o desempenho em dispositivos mais antigos e restritos.
  • Como o WOFF e o WOFF 2.0 abrangem todas as bases para navegadores modernos e legados ainda em uso, o uso de EOT e TTF não é mais necessário e pode resultar em tempos de download de fontes da Web mais longos.

Fontes da Web e compactação

O WOFF e o WOFF 2.0 têm compressão integrada. A compressão interna do WOFF 2.0 usa Brotli e oferece até 30% de compressão a mais do que o WOFF. Para mais informações, consulte o relatório de avaliação do WOFF 2.0.

Por fim, é bom saber que alguns formatos de fonte contêm metadados adicionais, como informações de hinting e kerning de fontes, que podem ser desnecessárias em algumas plataformas, o que permite otimizar ainda mais o tamanho do arquivo. Por exemplo, o Google Fonts mantém mais de 30 variantes otimizadas para cada fonte e detecta e fornece automaticamente a variante ideal para cada plataforma e navegador.

Definir uma família de fontes com @font-face

A at-rule CSS @font-face permite definir o local de um determinado recurso de fonte, suas características de estilo e os codepoints Unicode para os quais deve ser usado. Uma combinação dessas declarações @font-face pode ser usada para construir uma "família de fontes", que o navegador vai usar para avaliar quais recursos de fonte precisam ser baixados e aplicados à página atual.

Considere uma fonte variável

As fontes variáveis podem reduzir significativamente o tamanho do arquivo de fontes em casos em que você precisa de várias variantes de uma fonte. Em vez de carregar os estilos normal e em negrito, além das versões em itálico, você pode carregar um único arquivo com todas as informações. No entanto, os tamanhos de arquivos de fontes variáveis são maiores do que uma variante de fonte individual, mas menores do que a combinação de muitas variantes. Em vez de uma fonte variável grande, pode ser melhor exibir primeiro as variantes de fonte essenciais, com outras variantes sendo baixadas depois.

Agora todos os navegadores modernos oferecem suporte a fontes variáveis. Saiba mais na Introdução às fontes variáveis na Web.

Selecione o formato certo

Cada declaração @font-face especifica o nome da família de fontes, que atua como um grupo lógico de várias declarações, propriedades de fonte, como estilo, peso e extensão, e o descritor src, que especifica uma lista priorizada de locais do recurso de fonte.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       /* Only serve WOFF if necessary. Otherwise,
          WOFF 2.0 is fine by itself. */
       url('/fonts/awesome.woff') format('woff');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'),
       url('/fonts/awesome-i.woff') format('woff');
}

Antes de mais nada, observe que os exemplos acima definem uma única família Awesome Font com dois estilos (normal e itálico), cada um deles apontando para um conjunto diferente de recursos de fonte. Por sua vez, cada descritor src contém uma lista priorizada de variantes do recurso, separadas por vírgula:

  • A diretiva local() permite referenciar, carregar e usar fontes instaladas localmente. Se o usuário já tiver a fonte instalada no sistema, isso vai contornar a rede por completo e será a opção mais rápida.
  • A diretiva url() permite carregar fontes externas e pode conter uma dica opcional format(), indicando o formato da fonte referenciada pelo URL especificado.

Quando o navegador determina que a fonte é necessária, percorre a lista de recursos fornecida na ordem especificada e tenta carregar o recurso apropriado. Por exemplo, seguindo o exemplo acima:

  1. O navegador executa o layout da página e determina quais variantes de fontes são necessárias para renderizar o texto especificado na página. As fontes que não fazem parte do CSS Object Model (CSSOM) da página não são baixadas pelo navegador, porque não são necessárias.
  2. Para cada fonte necessária, o navegador verifica se a fonte está disponível localmente.
  3. Se a fonte não está disponível localmente, o navegador percorre as definições externas:
    • Se uma dica de formato estiver presente, o navegador verificará se ela é permitida antes de iniciar o download. Se não oferecer suporte para a dica, o navegador avança para a próxima.
    • Se nenhuma dica de formato estiver presente, o navegador fará o download do recurso.

A combinação de diretivas locais e externas com dicas de formato adequadas permite especificar todos os formatos de fonte disponíveis e deixar que o navegador se encarregue do resto. O navegador determina quais recursos são necessários e seleciona o formato ideal.

Subconjuntos de intervalo Unicode

Além das propriedades de fonte como estilo, peso e extensão, a regra @font-face permite definir um conjunto de codepoints Unicode compatível com cada recurso. Isso permite dividir uma fonte Unicode grande em subconjuntos menores (por exemplo, subconjuntos latino, cirílico e grego) e fazer o download apenas dos glifos necessários para renderizar o texto em uma determinada página.

O descritor unicode-range permite especificar uma lista delimitada por vírgulas contendo valores de intervalos. Cada intervalo pode ter um destes três formatos diferentes:

  • Único codepoint (por exemplo, U+416)
  • Intervalo (por exemplo, U+400-4ff): indica os codepoints inicial e final de um intervalo
  • Intervalo de caracteres curinga (por exemplo, U+4??): os caracteres ? indicam qualquer dígito hexadecimal

Por exemplo, você pode dividir sua família Awesome Font nos subconjuntos latino e japonês, que serão baixados individualmente pelo navegador conforme a necessidade:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-jp.woff2') format('woff2');
  /* Japanese glyphs */
  unicode-range: U+3000-9FFF, U+ff??;
}

O uso de subconjuntos de intervalos Unicode e de arquivos separados para cada variante de estilo da fonte permite definir uma família de fontes composta com download mais rápido e eficiente. Os visitantes baixam apenas as variantes e subconjuntos necessários e não são forçados a baixar subconjuntos que nunca serão vistos ou usados na página.

Quase todos os navegadores oferecem suporte a unicode-range. Para compatibilidade com navegadores mais antigos, talvez seja necessário usar a "criação manual de subconjuntos". Nesse caso, é preciso usar um único recurso de fonte que contenha todos os subconjuntos necessários e ocultar os demais do navegador. Por exemplo, se a página usar apenas caracteres latinos, pode-se eliminar outros glifos e servir esse subconjunto específico como um recurso independente.

  1. Determine quais subconjuntos são necessários:
    • Se o navegador suportar a criação de subconjuntos com unicode-range, o subconjunto correto será selecionado automaticamente. A página precisa apenas fornecer os arquivos de subconjuntos e especificar unicode-ranges adequados nas regras de @font-face.
    • Se o navegador não suportar a criação de subconjuntos com unicode-range, a página precisará ocultar todos os subconjuntos desnecessários. Ou seja, o desenvolvedor terá de especificar os subconjuntos necessários.
  2. Gerar subconjuntos de fontes:
    • Use a ferramenta pyftsubset de código aberto para criar subconjuntos e otimizar suas fontes.
    • Alguns servidores de fontes, como a fonte do Google, vão fazer o subconjunto automaticamente por padrão.
    • Alguns serviços de fontes permitem a criação manual de subconjuntos por meio de parâmetros de consulta personalizada, que podem ser usados para especificar manualmente o subconjunto necessário para a página. Consulte a documentação do seu provedor de fontes.

Seleção e síntese de fontes

Cada família de fontes pode ser composta de diversas variantes de estilo (regular, negrito, itálico) e diversos pesos para cada estilo. Cada um deles pode conter formas de glifos muito diferentes, por exemplo, espaçamento ou tamanho diferentes ou uma forma totalmente distinta.

Espessuras da fonte

O diagrama acima ilustra uma família de fontes que oferece três pesos de negrito diferentes:

  • 400 (regular).
  • 700 (negrito).
  • 900 (negrito extra).

Todas as outras variantes intermediárias (indicadas em cinza) são mapeadas automaticamente para a variante mais próxima pelo navegador.

Quando um peso especificado não tem uma face correspondente, é usada uma face com peso próximo. Em geral, pesos de negrito são mapeados a tipos de fonte com pesos maiores e pesos leves são mapeados a tipos de fonte com pesos menores.

Algoritmo de correspondência de fontes CSS

Uma lógica semelhante se aplica às variantes itálicas. O designer de fontes controla quais variantes serão produzidas, e você controla quais variantes vai usar na página. Como cada variante é um download separado, é uma boa ideia manter o número de variantes pequeno. Por exemplo, você pode definir duas variantes em negrito para a família Awesome Font:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 700;
  src: local('Awesome Font'),
       url('/fonts/awesome-l-700.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

O exemplo acima declara a família Awesome Font, que é composta por dois recursos que abrangem o mesmo conjunto de glifos latinos (U+000-5FF), mas oferecem dois "pesos" diferentes: normal (400) e negrito (700). No entanto, o que acontecerá se uma de suas regras CSS especificar um peso de fonte diferente ou definir a propriedade font-style como italic?

  • Se uma correspondência exata de fonte não estiver disponível, o navegador vai substituir a correspondência mais próxima.
  • Se nenhuma correspondência de estilo for encontrada (por exemplo, se nenhuma variante em itálico no exemplo acima foi declarada), o navegador sintetizará sua própria variante de fonte.
Síntese de fontes

O exemplo acima ilustra a diferença entre a fonte Open Sans real e a sintetizada. Todas as variantes sintetizadas foram geradas de uma única fonte com peso 400. Como você pode ver, há uma diferença visível nos resultados. Os detalhes de como gerar as variantes negrito e oblíquo não são especificados. Portanto, os resultados variam de navegador para navegador e dependem muito da fonte.

Lista de verificação para a otimização do tamanho da fonte da Web

  • Confira e monitore o uso de fontes:não use muitas fontes nas páginas. Para cada fonte, minimize o número de variantes usadas. Isso ajuda a produzir uma experiência mais consistente e rápida para seus usuários.
  • Evite formatos legados, se possível:os formatos EOT, TTF e WOFF são maiores que o WOFF 2.0. EOT e TTF são formatos estritamente desnecessários, enquanto WOFF pode ser aceitável se você precisar oferecer suporte ao Internet Explorer 11. Se você estiver segmentando apenas navegadores modernos, usar apenas o WOFF 2.0 é a opção mais simples e com melhor desempenho.
  • Crie um subconjunto dos recursos de fonte:várias fontes permitem a criação de subconjuntos ou a divisão em vários intervalos Unicode para fornecer apenas os glifos necessários para uma determinada página. Isso reduz o tamanho do arquivo e aumenta a velocidade do download do recurso. No entanto, ao definir os subconjuntos, tenha o cuidado de otimizar considerando a reutilização de fontes. Por exemplo, não faça o download de um conjunto de caracteres diferente, mas com caracteres iguais em cada página. Uma boa prática é criar um subconjunto de acordo com o sistema de escrita: por exemplo, latino e cirílico.
  • Dê preferência a local() na lista src:listar local('Font Name') primeiro na lista src garante que as solicitações HTTP não sejam feitas para fontes que já estão instaladas.
  • Use o Lighthouse para testar a compactação de texto.

Efeitos na maior exibição de conteúdo (LCP) e no deslocamento cumulativo do layout (CLS)

Dependendo do conteúdo da página, os nós de texto podem ser considerados candidatos para a Largest Contentful Paint (LCP). Portanto, é essencial seguir os conselhos deste artigo para garantir que as fontes da Web sejam o mais pequenas possível, para que os usuários possam ler o texto da página o mais rápido possível.

Se você acha que, apesar dos seus esforços de otimização, o texto da página pode demorar muito para aparecer devido ao recurso de fonte da Web grande, a propriedade font-display tem várias configurações que podem ajudar a evitar texto invisível enquanto uma fonte é transferida por download. No entanto, o uso do valor swap pode causar mudanças significativas no layout que afetam o Cumulative Layout Shift (CLS) do site. Se possível, use os valores optional ou fallback.

Se as fontes da Web forem essenciais para sua marca e, por extensão, para a experiência do usuário, considere pré-carregá-las para que o navegador tenha uma vantagem na solicitação delas. Isso pode reduzir o período de troca se você usar font-display: swap ou o período de bloqueio se você não estiver usando font-display.