Reduzir o tamanho da fonte na Web

A tipografia é fundamental para um bom design, branding, legibilidade e acessibilidade. As fontes da Web permitem tudo isso e muito mais: o texto pode ser selecionado, pesquisado, ampliado e é compatível com DPI alto, oferecendo uma renderização de texto consistente e nítida, independente do tamanho e da resolução da tela. As webfonts são essenciais para um bom design, UX e desempenho.

A otimização de fontes da Web é uma parte essencial da estratégia geral de performance. Cada fonte é um recurso adicional, e algumas podem bloquear a renderização do texto. No entanto, o fato de a página usar WebFonts não significa que ela precisa ser renderizada mais lentamente. Pelo contrário, fontes otimizadas, combinadas com uma estratégia adequada de carregamento e aplicação na página, podem ajudar a reduzir o tamanho total da página e melhorar os tempos de renderização.

Anatomia de uma fonte da Web

Uma fonte da Web é uma coleção de glifos, e cada glifo é uma forma vetorial que descreve uma letra ou um 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 uma fonte específica. Por exemplo, a Open Sans, uma das WebFonts mais usadas, contém 897 glifos, incluindo caracteres latinos, gregos e cirílicos.

Tabela de glifos de fonte

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

Nesta postagem, você vai descobrir como reduzir o tamanho do arquivo entregue das suas fontes da Web.

Formatos de fontes da Web

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

WOFF e WOFF 2.0 têm ampla compatibilidade e são aceitos por todos os navegadores modernos.

  • Veicule a variante WOFF 2.0 em navegadores modernos.
  • Se for absolutamente necessário, como se você ainda precisar oferecer suporte ao Internet Explorer 11, por exemplo, disponibilize o WOFF como um substituto.
  • Outra opção é não usar fontes da Web em navegadores legados e voltar para as fontes do sistema. Isso também pode ser mais eficiente para dispositivos mais antigos e com mais restrições.
  • 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 mais longos para fontes da Web.

Fontes da Web e compactação

Os formatos WOFF e WOFF 2.0 têm compactação integrada. A compactação interna do WOFF 2.0 usa Brotli e oferece até 30% de melhoria na compactação em comparação com o WOFF. Para mais informações, consulte o relatório de avaliação do WOFF 2.0.

Por fim, vale a pena observar que alguns formatos de fonte contêm metadados adicionais, como dicas de fonte e informações de kerning que podem não ser necessárias em algumas plataformas, o que permite uma maior otimização do tamanho do arquivo. Por exemplo, o Google Fonts mantém mais de 30 variantes otimizadas para cada fonte e detecta e entrega automaticamente a variante ideal para cada plataforma e navegador.

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

A regra at @font-face do CSS permite definir a localização de um recurso de fonte específico, as características de estilo e os pontos de código Unicode para os quais ele deve ser usado. Uma combinação dessas declarações @font-face pode ser usada para construir uma "família tipográfica", que o navegador usa 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 dos arquivos de fontes quando você precisa de várias variantes de uma fonte. Em vez de precisar carregar os estilos normal e 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, talvez seja melhor veicular primeiro as variantes de fonte críticas e baixar outras variantes depois.

As fontes variáveis agora são compatíveis com todos os navegadores modernos. Saiba mais em Introdução às fontes variáveis na Web.

Selecionar o formato certo

Cada declaração @font-face fornece o nome da família tipográfica, que funciona 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 para o 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');
}

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

  • A diretiva local() permite referenciar, carregar e usar fontes instaladas localmente. Se o usuário já tiver a fonte instalada no sistema, isso vai ignorar a rede completamente e será o mais rápido.
  • A diretiva url() permite carregar fontes externas e pode conter uma dica format() opcional que indica o formato da fonte referenciada pelo URL fornecido.

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

  1. O navegador realiza o layout da página e determina quais variantes de fonte são necessárias para renderizar o texto especificado na página. As fontes que não fazem parte do modelo de objeto CSS (CSSOM) da página não são baixadas pelo navegador, já que não são necessárias.
  2. Para cada fonte necessária, o navegador verifica se ela está disponível localmente.
  3. Se a fonte não estiver disponível localmente, o navegador vai iterar pelas definições externas:
    • Se houver uma dica de formato, o navegador vai verificar se ela é compatível antes de iniciar o download. Se o navegador não for compatível com a dica, ele vai para a próxima.
    • Se não houver uma dica de formato, o navegador vai baixar o 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 cuide do restante. O navegador determina quais recursos são necessários e seleciona o formato ideal.

Subconfiguração de intervalo Unicode

Além das propriedades de fonte, como estilo, peso e extensão, a regra @font-face permite definir um conjunto de pontos de código Unicode compatíveis com cada recurso. Isso permite dividir uma fonte Unicode grande em subconjuntos menores (por exemplo, subconjuntos latinos, cirílicos e gregos) e baixar apenas os glifos necessários para renderizar o texto em uma página específica.

O descritor unicode-range permite especificar uma lista de valores de intervalo delimitada por vírgulas, cada um deles em uma de três formas diferentes:

  • Ponto de código único (por exemplo, U+416)
  • Intervalo (por exemplo, U+400-4ff): indica os pontos de código inicial e final de um intervalo.
  • Intervalo de caracteres curinga (por exemplo, U+4??): ? caracteres indicam qualquer dígito hexadecimal

Por exemplo, você pode dividir sua família Awesome Font em subconjuntos latinos e japoneses, cada um deles baixado pelo navegador conforme necessário:

@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 arquivos separados para cada variante estilística da fonte permite definir uma família de fontes composta que é mais rápida e eficiente para download. Os visitantes só baixam as variantes e os subconjuntos de que precisam, sem serem obrigados a baixar subconjuntos que talvez nunca vejam ou usem na página.

Quase todos os navegadores são compatíveis com unicode-range. Para compatibilidade com navegadores mais antigos, talvez seja necessário voltar à "substituição manual". Nesse caso, você precisa fornecer um único recurso de fonte que contenha todos os subconjuntos necessários e ocultar o restante do navegador. Por exemplo, se a página estiver usando apenas caracteres latinos, você poderá remover outros glifos e veicular esse subconjunto específico como um recurso independente.

  1. Determine quais subconjuntos são necessários:
    • Se o navegador for compatível com a subdefinição de unicode-range, ele vai selecionar automaticamente o subconjunto certo. A página só precisa fornecer os arquivos de subconjunto e especificar intervalos unicode adequados nas regras @font-face.
    • Se o navegador não oferecer suporte à inclusão de subconjuntos unicode-range, a página precisará ocultar todos os subconjuntos desnecessários. Ou seja, o desenvolvedor precisa 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 o Google Fonts, fazem o subconjunto automaticamente por padrão.
    • Alguns serviços de fontes permitem a criação manual de subconjuntos usando parâmetros de consulta personalizados, que podem ser usados para especificar manualmente o subconjunto necessário para sua página. Consulte a documentação do provedor de fontes.

Seleção e síntese de fontes

Cada família de fontes pode ser composta de várias variantes estilísticas (normal, negrito, itálico) e várias espessuras para cada estilo. Cada uma delas, por sua vez, pode conter formatos de glifos muito diferentes, por exemplo, espaçamento, dimensionamento ou formato totalmente diferentes.

Espessuras da fonte

O diagrama acima ilustra uma família tipográfica que oferece três pesos diferentes em negrito:

  • 400 (comum).
  • 700 (negrito).
  • 900 (extranegrito).

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 para o qual não existe um rosto, um rosto com um peso próximo é usado. Em geral, os pesos em negrito são mapeados para famílias tipográficas com pesos mais pesados, e os pesos leves são mapeados para famílias tipográficas com pesos mais leves.

Algoritmo de correspondência de fontes CSS

Uma lógica semelhante se aplica às variantes itálico. O designer de fontes controla quais variantes serão produzidas, e você controla quais variantes serão usadas na página. Como cada variante é um download separado, é recomendável 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 acontece se uma das suas regras de CSS especificar uma espessura de fonte diferente ou definir a propriedade font-style como italic?

  • Se não houver uma correspondência exata, o navegador vai substituir pela opção mais próxima.
  • Se nenhuma correspondência estilística for encontrada (por exemplo, nenhuma variante em itálico foi declarada no exemplo acima), o navegador vai sintetizar a própria variante de fonte.
Síntese de fontes

O exemplo acima ilustra a diferença entre os resultados de fontes reais e sintetizadas para Open Sans. Todas as variantes sintetizadas são geradas com uma única fonte de peso 400. Como você pode ver, há uma diferença notável nos resultados. Os detalhes de como gerar as variantes em 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 otimização do tamanho da fonte da Web

  • Audite e monitore o uso de fontes:não use muitas fontes nas suas páginas e, para cada uma delas, minimize o número de variantes usadas. Isso ajuda a produzir uma experiência mais consistente e rápida para os 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ê segmenta apenas navegadores modernos, usar apenas WOFF 2.0 é a opção mais simples e com melhor desempenho.
  • Crie um subconjunto dos recursos de fonte:muitas fontes podem ser divididas em subconjuntos ou em vários intervalos Unicode para fornecer apenas os glifos necessários em uma página específica. Isso reduz o tamanho do arquivo e melhora a velocidade de download do recurso. No entanto, ao definir os subconjuntos, tenha cuidado para otimizar a reutilização de fontes. Por exemplo, não baixe um conjunto de caracteres diferente, mas sobreposto, em cada página. Uma boa prática é criar subconjuntos com base no script, por exemplo, latino e cirílico.
  • Dê precedência a local() na sua lista src:listar local('Font Name') primeiro na sua lista src garante que as solicitações HTTP não sejam feitas para fontes já instaladas.
  • Use o Lighthouse para testar a compactação de texto.

Efeitos na Largest Contentful Paint (LCP) e na Cumulative Layout Shift (CLS)

Dependendo do conteúdo da página, os nós de texto podem ser considerados candidatos para a Largest Contentful Paint (LCP). Por isso, é vital garantir que as fontes da Web sejam o menor possível seguindo as dicas deste artigo para que os usuários vejam o texto na sua página assim que possível.

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

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