Reduzir o tamanho da fonte na Web

A tipografia é fundamental para um bom design, marca, legibilidade e acessibilidade. As fontes da Web permitem tudo isso e muito mais: o texto é selecionável, pesquisável, ampliável e fácil de usar 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 oferecer design, experiência de usuário e desempenho de qualidade.

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. No entanto, o uso de WebFonts não significa que a renderização da página será mais lenta. 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 o tempo 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, Open Sans, uma das WebFonts mais conhecidas, 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 sua 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 tem como objetivo oferecer suporte a todos os idiomas do mundo. Observe, entretanto, que o tamanho total do Noto, com todos os idiomas incluídos, resulta em um download de ZIP com mais de 1,1 GB.

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

Formatos de fontes para a Web

Atualmente, existem dois formatos de contêiner de fonte recomendados em uso na Web:

WOFF e WOFF 2.0 contam com amplo suporte e são aceitos em todos os navegadores modernos.

  • Sirva a variante WOFF 2.0 para navegadores modernos.
  • Se for absolutamente necessário, por exemplo, caso você ainda precise de suporte ao Internet Explorer 11, disponibilize o WOFF como substituto.
  • Como alternativa, considere não usar fontes da Web em navegadores legados e recorrer às fontes do sistema. Isso também pode ter um desempenho melhor para dispositivos mais antigos e mais restritos.
  • Como WOFF e WOFF 2.0 abrangem todas as bases para navegadores modernos e legados ainda em uso, o uso de EOT e TTF não são mais necessários e podem resultar em tempos de download de fontes da web mais longos.

Fontes da Web e compactação

Tanto o WOFF quanto o WOFF 2.0 têm compressão integrada. A compressão interna do WOFF 2.0 usa Brotli e oferece uma compactação até 30% melhor do que o WOFF. Para mais informações, consulte o relatório de avaliação de WOFF 2.0 (link em inglês).

Por fim, é importante notar 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 envia automaticamente a variante ideal para cada plataforma e navegador.

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

A at-rule CSS do @font-face permite definir o local de um recurso de fonte específico, as características de estilo dele e os codepoints Unicode em que ele 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.

Usar uma fonte variável

Fontes variáveis podem reduzir significativamente o tamanho do arquivo das suas fontes nos casos em que você precisa de diversas variantes de uma fonte. Em vez de carregar os estilos regulares e negrito e suas versões em itálico, você pode carregar um único arquivo que contém todas as informações. No entanto, os tamanhos de arquivo de fonte 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 grande variável, talvez seja melhor veicular variantes críticas primeiro, com outras variantes baixadas mais tarde.

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

Selecione o formato correto

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 fonte como estilo, peso e alongamento, e o descritor src, que especifica uma lista priorizada de locais para o recurso da 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 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, a rede será ignorada e é a mais rápida.
  • A diretiva url() permite carregar fontes externas e podem conter uma dica opcional format(), indicando o formato da fonte referenciada pelo URL fornecido.
.

Quando o navegador determina que a fonte é necessária, ele 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 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, na sigla em inglês) da página não são transferidas por download pelo navegador, já que não são necessárias.
  2. O navegador verifica se cada fonte necessária está disponível localmente.
  3. Se a fonte não estiver disponível localmente, o navegador itera nas definições externas:
    • Se uma dica de formato estiver presente, o navegador verificará se ela é compatível 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 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.

Criar subconjuntos com Unicode-range

Além das propriedades de fonte como estilo, peso e extensão, a regra @font-face permite definir um conjunto de codepoints Unicode compatíveis 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 página específica.

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

  • Ponto de código único (por exemplo, U+416)
  • Intervalo de intervalo (por exemplo, U+400-4ff): indica os codepoints 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 a família Awesome Font em latim e japonês. subconjuntos, sendo que cada um deles é baixado 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 de estilo da fonte permite definir uma família de fontes composta com download mais rápido e eficiente. Os visitantes só fazem o download das variantes e dos subconjuntos necessários, sem que eles sejam forçados a fazer o download de subconjuntos que nunca serão vistos ou usados na página.

Quase todos os navegadores são compatíveis com o unicode-range. Para compatibilidade com navegadores mais antigos, talvez seja necessário recorrer à "criação manual de subconjuntos". Nesse caso, você tem que voltar a 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 usar apenas caracteres latinos, você poderá eliminar outros glifos e servir esse subconjunto específico como um recurso autônomo.

  1. Determine quais subconjuntos são necessários:
    • Se o navegador oferecer suporte à criação de subconjuntos com unicode-range, o subconjunto correto será selecionado automaticamente. A página só precisa fornecer os arquivos de subconjuntos e especificar unicode-ranges apropriados nas regras @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 precisa especificar os subconjuntos necessários.
  2. Gerar subconjuntos de fontes:
    • Use a ferramenta de código aberto pyftsubset (em inglês) para criar subconjuntos e otimizar suas fontes.
    • Alguns servidores de fontes, como o Google Fonts, fazem subconjuntos automaticamente por padrão.
    • Alguns serviços de fontes permitem a criação manual de subconjuntos por meio de parâmetros de consulta personalizados, que você pode usar para especificar manualmente o subconjunto necessário para sua 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 por diversas variantes de estilo (regular, negrito, itálico) e diversos pesos para cada estilo. Cada um deles, por sua vez, pode conter formas de glifo muito diferentes, por exemplo, espaçamento ou tamanho diferentes ou uma forma totalmente diferente.

Espessura da fonte

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

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

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

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

Algoritmo de correspondência de fontes CSS

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

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

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

  • Faça uma auditoria e monitore o uso das fontes:não as use em excesso nas páginas e minimize o número de variantes usadas para cada fonte. 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 WOFF 2.0. EOT e TTF são formatos estritamente desnecessários, enquanto WOFF pode ser aceitável se você precisar de suporte para o Internet Explorer 11. Se você tem como alvo apenas navegadores modernos, usar apenas o WOFF 2.0 é a opção mais simples e com melhor desempenho.
  • Crie um subconjunto dos recursos de fontes:muitas fontes podem ser separadas ou divididas em vários intervalos de unicode para oferecer apenas os glifos necessários para uma determinada página. Isso reduz o tamanho do arquivo e melhora a velocidade de 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 sobreposto, em cada página. Um uma prática recomendada é criar subconjuntos com base no script: por exemplo, latino e cirílico.
  • Dê prioridade ao local() na sua lista src:listar o local('Font Name') primeiro na sua lista src garante que as solicitações HTTP não sejam feitas para as fontes que já estão 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 à Maior exibição de conteúdo (LCP). Por isso, é vital garantir que suas fontes da Web sejam as menores possíveis seguindo as recomendações deste artigo para que os usuários vejam o texto na sua página assim que possível.

Se você acredita que, apesar dos seus esforços de otimização, o texto da página pode demorar muito para aparecer devido ao grande recurso de fontes da Web, a propriedade font-display tem diversas configurações que podem ajudar a evitar texto invisível durante o download de uma fonte. No entanto, usar o valor swap pode causar mudanças de layout significativas que afetam a Cumulative Layout Shift (CLS, na sigla em inglês) do site. Considere usar os valores optional ou fallback, se possível.

Se suas fontes da Web são cruciais para sua marca e, por extensão, para a experiência do usuário, considere pré-carregar as fontes para que o navegador se prepare para solicitá-las. 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.