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 é selecionável, pesquisável, pode ser ampliado e é compatível com DPI alto, oferecendo uma renderização de texto consistente e nítida, independentemente 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 desempenho. Cada fonte é um recurso adicional, e algumas podem bloquear a renderização do texto, mas só porque a página está usando WebFonts não significa que ela precisa ser renderizada mais lentamente. Pelo contrário, fontes otimizadas, combinadas com uma estratégia criteriosa de como elas são carregadas e aplicadas 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 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, que é uma das WebFonts mais populares, 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 para vários idiomas, use uma fonte que possa oferecer uma aparência e 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 de 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:

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

  • Disponibilize a variante WOFF 2.0 para navegadores mais recentes.
  • Se for absolutamente necessário, por exemplo, se você ainda precisar oferecer suporte ao Internet Explorer 11, disponibilize o WOFF como um substituto.
  • Como alternativa, considere não usar fontes da Web para navegadores legados e voltar às fontes do sistema. Isso também pode ser mais eficiente para 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 compactação integrada. A compactação interna do WOFF 2.0 usa o Brotli e oferece até 30% de compactação melhor do que 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 fontes e 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 oferece automaticamente a variante ideal para cada plataforma e navegador.

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

A regra @font-face CSS permite definir o local 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 de fontes", que o navegador usará para avaliar quais recursos de fonte precisam ser baixados e aplicados à página atual.

Considerar uma fonte variável

As fontes variáveis podem reduzir significativamente o tamanho dos arquivos de fontes nos casos em que 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 que contenha todas as informações. No entanto, os tamanhos de arquivos de fontes variáveis serão maiores do que uma variante de fonte individual, embora menores do que a combinação de muitas variantes. Em vez de uma fonte variável grande, talvez seja melhor oferecer primeiro as variantes de fontes críticas, com outras variantes baixadas mais tarde.

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

Selecionar o formato certo

Cada declaração @font-face fornece o nome da família de fontes, que atua como um grupo lógico de várias declarações, propriedades de fontes como estilo, peso e alongamento, 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 deles 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 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 fonte 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 ela está disponível localmente.
  3. Se a fonte não estiver disponível localmente, o navegador vai iterar as definições externas:
    • Se uma dica de formato estiver presente, o navegador vai verificar se ela oferece suporte à dica antes de iniciar o download. Se o navegador não oferecer suporte à dica, ele vai avançar para a próxima.
    • Se nenhuma dica de formato estiver presente, 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 o restante para o navegador. O navegador determina quais recursos são necessários e seleciona o formato ideal.

Subconjunto de intervalo Unicode

Além das propriedades de fonte, como estilo, peso e alongamento, a regra @font-face permite definir um conjunto de pontos de código Unicode com suporte para 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 unicode-range descritor permite especificar uma lista de valores de intervalo separados por vírgulas, cada um dos quais pode estar 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??): os caracteres ? indicam qualquer dígito hexadecimal

Por exemplo, você pode dividir sua família Awesome Font em subconjuntos latinos e japoneses, cada um dos quais o navegador baixa 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 intervalo 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 e não são forçados a baixar subconjuntos que talvez nunca vejam ou usem na página.

Quase todos os navegadores oferecem suporte a unicode-range. Para compatibilidade com navegadores mais antigos, talvez seja necessário voltar ao "subconjunto 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 disponibilizar esse subconjunto específico como um recurso independente.

  1. Determinar quais subconjuntos são necessários:
    • Se o navegador oferecer suporte ao subconjunto de intervalo Unicode, ele vai selecionar automaticamente o subconjunto correto. 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 ao subconjunto de intervalo Unicode, 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 Font, vão criar subconjuntos 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ários pesos para cada estilo. Cada um deles, por sua vez, pode conter formas de glifos muito diferentes, por exemplo, espaçamento, tamanho ou uma forma completamente diferente.

Imagem mostrando a letra A com pesos de fonte cada vez maiores.

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

  • 400 (normal).
  • 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 uma face, uma face com um peso próximo é usada. Em geral, os pesos em negrito são mapeados para faces com pesos mais pesados e os pesos leves são mapeados para faces com pesos mais leves.

Algoritmo de correspondência de fontes CSS

Uma lógica semelhante se aplica às variantes itálicas. O designer de fontes controla quais variantes ele vai produzir, 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 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 CSS especificar um peso de fonte diferente ou definir a propriedade font-style como italic?

  • Se uma correspondência de fonte exata não estiver disponível, o navegador vai substituir a correspondência 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 fonte mostrando uma declaração "lorem ipsum" de pesos 300 a 800 com entradas em itálico alternadas.

O exemplo acima ilustra a diferença entre os resultados de fontes reais e sintetizadas para a Open Sans. Todas as variantes sintetizadas são geradas a partir de 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 de otimização de tamanho de fonte da Web

  • Audite e monitore o uso de fontes:não use muitas fontes nas suas páginas e, para cada fonte, 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 do que o WOFF 2.0. EOT e TTF são formatos estritamente desnecessários, enquanto o 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 eficiente.
  • Subconjunto de recursos de fonte:muitas fontes podem ser subconjuntos ou divididas em vários intervalos Unicode para oferecer apenas os glifos necessários para 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.
  • Priorize 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 oLighthouse para testar a compactação de texto.

Efeitos no Largest Contentful Paint (LCP) e no 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). Portanto, é fundamental garantir que as fontes da Web sejam o menor possível, seguindo as orientações deste artigo, para que os usuários vejam o texto na página assim que possível.

Se você estiver preocupado 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 a evitar texto invisível enquanto uma fonte está sendo baixada. No entanto, o uso do valor swap pode causar mudanças significativas no layout que afetam a Cumulative Layout Shift (CLS) do seu site. Considere usar os valores optional ou fallback, se possível.

Se as fontes da Web forem essenciais para o branding e, por extensão, para a experiência do usuário, considere pré-carregar as fontes para que o navegador tenha um início 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 não estiver usando font-display.