Reduzir o tamanho da fonte na Web

A tipografia é fundamental para um bom design, branding, legibilidade e acessibilidade. As fontes da Web oferecem tudo isso e muito mais: o texto é selecionável, pesquisável, ampliável e compatível com alto DPI, proporcionando renderização de texto consistente e nítida, independentemente do tamanho e da resolução da tela. WebFonts são essenciais para um bom design, UX e desempenho.

A otimização de fontes da Web é uma parte fundamental da estratégia geral de desempenho. Cada fonte é um recurso adicional, e algumas fontes podem bloquear a renderização do texto, mas só porque a página está usando WebFonts não significa que ela terá que 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 a melhorar seus tempos 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 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 determinada fonte. Por exemplo, Open Sans, que é uma das WebFonts mais populares, 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 suportados. Se você precisar localizar o conteúdo da sua página para vários idiomas, use uma fonte que ofereça 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, porém, 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 enviado para suas fontes da Web.

Formatos de fonte da Web

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

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

  • Sirva a variante WOFF 2.0 para navegadores mais recentes.
  • Se for absolutamente necessário (por exemplo, caso você ainda precise de suporte ao Internet Explorer 11, por exemplo), disponibilize o WOFF como substituto.
  • Outra opção é não usar fontes da Web para navegadores legados e recorrer às fontes do sistema. Isso pode ter melhor desempenho também em dispositivos mais antigos e mais 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 compressão interna do WOFF 2.0 usa o Brotli e oferece compressão até 30% melhor que a do WOFF. Para mais informações, consulte o relatório de avaliação do WOFF 2.0.

Por fim, é importante notar que alguns formatos de fonte contêm metadados adicionais, como informações de dicas de fonte e kerning que podem não ser necessárias em algumas plataformas, o que permite uma otimização adicional 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 e os codepoints Unicode para os quais ele precisa ser usado. Uma combinação dessas declarações @font-face pode ser usada para criar uma "família de fontes", que o navegador usa para avaliar quais recursos de fonte precisam ser transferidos por download e aplicados à página atual.

Use uma fonte variável

Fontes variáveis podem reduzir significativamente o tamanho do arquivo das fontes quando são necessárias diversas variantes de uma fonte. Em vez de precisar carregar os estilos regulares e em negrito e suas versões em itálico, você pode carregar um único arquivo que contenha todas as informações. No entanto, os tamanhos dos arquivos de fontes variáveis serã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 críticas, para que as outras variantes sejam baixadas depois.

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

Selecione 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 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 deles apontando para um conjunto diferente de recursos de fonte. Por sua vez, cada descritor src contém uma lista priorizada e separada por vírgulas 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, a rede será totalmente ignorada e esta é a opção mais rápida.
  • A diretiva url() permite carregar fontes externas e pode incluir uma dica format() opcional indicando o formato da fonte referenciada pelo URL fornecido.

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 fonte são necessárias para renderizar o texto especificado na página. Fontes que não fazem parte do CSS Object Model (CSSOM) da página não são transferidas por download 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 itera sobre as definições externas:
    • Se uma dica de formato estiver presente, o navegador verificará se ela é permitida antes de iniciar o download. Se o navegador não for compatível com a dica, ele 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 faça o resto. O navegador determina quais recursos são necessários e seleciona o formato ideal.

Criar subconjuntos com Unicode-range

Além das propriedades da 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 de valores de intervalos delimitados por vírgulas, cada um podendo estar em 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 a família Awesome Font em subconjuntos latino e japonês, que serão transferidos por download 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 de arquivos separados para cada variante de estilo da fonte permite que você defina uma família de fontes compostas com download mais rápido e eficiente. Os visitantes só fazem o download das variantes e dos subconjuntos de que precisam e não são 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 unicode-range. Para compatibilidade com navegadores mais antigos, talvez seja necessário voltar à "criação manual de subconjuntos". Nesse caso, será necessário 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 só usar caracteres latinos, é possível eliminar outros glifos e disponibilizar esse subconjunto específico como um recurso independente.

  1. Determine quais subconjuntos são necessários:
    • Se o navegador for compatível com a 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 adequados nas regras @font-face.
    • Se o navegador não oferecer suporte à criação de subconjuntos com unicode-range, a página precisará ocultar todos os subconjuntos desnecessários. Ou seja, o desenvolvedor precisará especificar os subconjuntos necessários.
  2. Gere subconjuntos de fontes:
    • Use a ferramenta pyftsubset (link em inglês) de código aberto para criar subconjuntos e otimizar suas fontes.
    • O subconjunto de alguns servidores de fontes, como o Google Fonts, é feito 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 dos quais, por sua vez, pode conter formas de glifo muito diferentes, por exemplo, espaçamento ou tamanho diferentes ou uma forma totalmente diferente.

Espessuras da fonte

O diagrama acima ilustra uma família de fontes que oferece três pesos em 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 um rosto, é usado um com peso próximo. Em geral, pesos em negrito são associados a faces com pesos maiores, e pesos leves são mapeados a faces com pesos menores.

Algoritmo de correspondência de fontes do 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, é 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 acontecerá se uma das regras de CSS especificar uma espessura 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, nenhuma variante em itálico foi declarada no exemplo acima), o navegador sintetizará sua própria variante de fonte.
Síntese de fonte

O exemplo acima ilustra a diferença entre os resultados da fonte Open Sans real e a sintetizada. Todas as variantes sintetizadas são geradas de uma única fonte com peso 400. É possível notar uma diferença perceptível nos resultados. Os detalhes de como gerar as variantes em negrito e oblíquos 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 do tamanho de fonte da Web

  • Faça uma auditoria e monitore o uso de fontes:não use fontes demais 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 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, já que WOFF pode ser aceitável se você precisar oferecer suporte ao Internet Explorer 11. Se você segmentar somente navegadores modernos, usar o WOFF 2.0 somente é a opção mais simples e com melhor desempenho.
  • Divida seus recursos de fontes:muitas fontes podem ser em subconjuntos ou divididas em vários intervalos de unicode para oferecer apenas os glifos necessários para uma página específica. Isso reduz o tamanho do arquivo e aumenta 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. Uma boa prática é criar um subconjunto de acordo com o script: por exemplo, latino e cirílico.
  • Dê prioridade a local() na sua 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 Largest Contentful Paint (LCP) e 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). Portanto, é fundamental garantir que as fontes da Web sejam as menores possíveis. Para isso, siga as recomendações deste artigo para que os usuários vejam o texto na sua página assim que possível.

Se você teme que, apesar dos seus esforços de otimização, o texto da página demore muito para aparecer devido ao grande recurso de fonte da Web, a propriedade font-display tem várias 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 significativas de layout que afetam a Mudança de layout cumulativa (CLS, na sigla em inglês) do site. Considere usar os valores optional ou fallback, se possível.

Se suas fontes da Web forem cruciais para sua marca e, consequentemente, para a experiência do usuário, considere pré-carregar suas 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 você não estiver usando font-display.