Práticas recomendadas para fontes

Otimizar fontes da Web para as Core Web Vitals.

Este documento discute as práticas recomendadas de performance para fontes. Há várias maneiras pelas quais as fontes da Web afetam a performance:

Este documento tem três seções: carregamento de fontes, fornecimento de fontes e renderização de fontes. Cada seção explica como esse aspecto específico do ciclo de vida da fonte funciona e oferece as práticas recomendadas correspondentes.

Carregamento de fontes

As fontes são recursos importantes. Sem elas, o usuário pode não conseguir visualizar o conteúdo da página. Assim, as práticas recomendadas para carregamento de fontes geralmente se concentram em garantir que as fontes sejam carregadas o mais cedo possível. É preciso ter cuidado especial com as fontes carregadas de sites de terceiros, já que o download desses arquivos de fonte exige configurações de conexão separadas.

Se você não tiver certeza se as fontes da página estão sendo solicitadas a tempo, confira a guia Timing no painel Network do Chrome DevTools para mais informações.

A guia "Tempo" no DevTools.

Entender @font-face

Antes de analisar as práticas recomendadas para carregamento de fontes, é importante entender como @font-face funciona e como isso afeta o carregamento de fontes.

A @font-face declaração é uma parte essencial do trabalho com qualquer fonte da Web. No mínimo, ela declara o nome usado para se referir à fonte e indica o local do arquivo de fonte correspondente.

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

Um equívoco comum é que uma fonte é solicitada quando uma declaração @font-face é encontrada. Isso é falso. Por si só, a declaração @font-face não aciona o download da fonte. Em vez disso, uma fonte é baixada apenas se for referenciada por um estilo usado na página. Exemplo:

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

h1 {
  font-family: "Open Sans"
}

Neste exemplo, Open Sans só seria baixado se a página contivesse um <h1> elemento.

Assim, ao pensar na otimização de fontes, é importante dar às folhas de estilo a mesma consideração que aos arquivos de fonte. Mudar o conteúdo ou a entrega de folhas de estilo pode ter um impacto significativo no momento em que as fontes chegam. Da mesma forma, remover CSS não usado e dividir folhas de estilo pode reduzir o número de fontes carregadas por uma página.

Declarações de fontes inline

A maioria dos sites se beneficiaria muito da incorporação de declarações de fontes e outros estilos críticos no <head> do documento principal, em vez de incluí-los em uma folha de estilo externa. Isso permite que o navegador descubra as declarações de fontes mais cedo, já que não precisa esperar o download da folha de estilo externa.

<head>
  <style>
    @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    }

    body {
        font-family: "Open Sans";
    }

    ...etc.

  </style>
</head>

A incorporação de CSS crítico pode ser uma técnica mais avançada que nem todos os sites podem alcançar. Os benefícios de performance são claros, mas exigem processos e ferramentas de build adicionais para garantir que o CSS necessário, e idealmente apenas o CSS crítico, seja incorporado corretamente e que qualquer CSS adicional seja entregue de maneira não bloqueadora de renderização.

Pré-conectar a origens de terceiros críticas

Se o site carregar fontes de um site de terceiros, é altamente recomendável que você use a dica de recurso preconnect para estabelecer conexões iniciais com a origem de terceiros. As dicas de recursos precisam ser colocadas no <head> do documento. A dica de recurso a seguir configura uma conexão para carregar a folha de estilo da fonte.

<head>
  <link rel="preconnect" href="https://fonts.com">
</head>

Para pré-conectar a conexão usada para baixar o arquivo de fonte, adicione uma dica de recurso preconnect separada que use o atributo crossorigin. Ao contrário das folhas de estilo, os arquivos de fonte precisam ser enviados por uma conexão CORS.

<head>
  <link rel="preconnect" href="https://fonts.com">
  <link rel="preconnect" href="https://fonts.com" crossorigin>
</head>

Ao usar a dica de recurso preconnect, lembre-se de que um provedor de fontes pode disponibilizar folhas de estilo e fontes de origens separadas. Por exemplo, é assim que a dica de recurso preconnect seria usada para o Google Fonts.

<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

Tenha cuidado ao usar preload para carregar fontes

Embora preload seja altamente eficaz para tornar as fontes detectáveis no início do processo de carregamento de página, isso tem o custo de retirar recursos do navegador do carregamento de outros recursos.

A incorporação de declarações de fontes e o ajuste de folhas de estilo podem ser uma abordagem mais eficaz. Esses ajustes se aproximam da causa raiz das fontes descobertas tardiamente, em vez de apenas fornecer uma solução alternativa.

Além disso, o uso de preload como uma estratégia de carregamento de fontes também precisa ser feito com cuidado, já que ele ignora algumas das estratégias de negociação de conteúdo integradas do navegador. Por exemplo, preload ignora declarações unicode-range e, se usado com prudência, só deve ser usado para carregar um único formato de fonte.

No entanto, ao usar folhas de estilo externas, o pré-carregamento das fontes mais importantes pode ser muito eficaz, já que o navegador não vai descobrir se a fonte é necessária até muito mais tarde.

Fornecimento de fontes

O fornecimento mais rápido de fontes resulta em uma renderização de texto mais rápida. Além disso, se uma fonte for entregue cedo o suficiente, isso poderá ajudar a eliminar mudanças de layout resultantes da troca de fontes.

Usar fontes auto-hospedadas

No papel, o uso de uma fonte auto-hospedada deve oferecer melhor performance, já que elimina uma configuração de conexão de terceiros. Na prática, as diferenças de performance entre essas duas opções são menos claras. Por exemplo, o Web Almanac descobriu que os sites que usam fontes de terceiros têm uma renderização mais rápida do que as fontes que usam fontes próprias.

Se você estiver considerando usar fontes auto-hospedadas, confirme se o site usa uma rede de fornecimento de conteúdo (CDN) e HTTP/2. Sem o uso dessas tecnologias, é muito menos provável que as fontes auto-hospedadas ofereçam melhor performance.

Se você usar uma fonte auto-hospedada, é recomendável aplicar também algumas das otimizações de arquivos de fonte que os provedores de fontes de terceiros normalmente fornecem automaticamente. Por exemplo, subconjunto de fontes e compactação WOFF2. A quantidade de esforço necessária para aplicar essas otimizações depende um pouco dos idiomas que seu site oferece suporte. Em particular, esteja ciente de que a otimização de fontes para idiomas CJK pode ser particularmente desafiadora.

Usar WOFF2

Das fontes modernas, a WOFF2 é a mais recente, tem o suporte mais amplo do navegador e oferece a melhor compactação. Como usa o Brotli, o WOFF2 compacta 30% melhor do que o WOFF, o que leva a menos dados para baixar e, portanto, a uma performance mais rápida.

Dado o suporte do navegador, os especialistas agora recomendam usar apenas o WOFF2:

Na verdade, achamos que também é hora de proclamar: use apenas o WOFF2 e esqueça todo o resto.

Isso vai simplificar muito seu CSS e fluxo de trabalho, além de evitar downloads acidentais de fontes duplas ou incorretas. O WOFF2 agora é compatível em todos os lugares. Portanto, a menos que você precise oferecer suporte a navegadores muito antigos, use apenas o WOFF2. Se não for possível, considere não disponibilizar nenhuma fonte da Web para esses navegadores mais antigos. Isso não será um problema se você tiver uma estratégia de fallback robusta. Os visitantes em navegadores mais antigos vão ver suas fontes de fallback.

Bram Stein, do Web Almanac de 2022

Subconjunto de fontes

Os arquivos de fonte normalmente incluem um grande número de glifos para todos os vários caracteres que eles oferecem suporte. No entanto, talvez você não precise de todos os caracteres na página e possa reduzir o tamanho dos arquivos de fonte por subconjunto de fontes.

O unicode-range descritor na declaração @font-face informa ao navegador para quais caracteres uma fonte pode ser usada.

@font-face {
    font-family: "Open Sans";
    src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    unicode-range: U+0025-00FF;
}

Um arquivo de fonte é baixado se a página contiver um ou mais caracteres que correspondam ao intervalo Unicode. unicode-range é usado com frequência para disponibilizar arquivos de fonte diferentes, dependendo do idioma usado pelo conteúdo da página.

unicode-range é frequentemente usado em conjunto com a técnica de subconjunto. Uma fonte de subconjunto inclui uma parte menor dos glifos contidos no arquivo de fonte original. Por exemplo, em vez de disponibilizar todos os caracteres para todos os usuários, um site pode gerar fontes de subconjunto separadas para caracteres latinos e cirílicos.

O número de glifos por fonte varia muito:

  • As fontes latinas geralmente têm de 100 a 1.000 glifos por fonte.
  • CJKCJK podem ter mais de 10.000 caracteres.

A remoção de glifos não usados pode reduzir significativamente o tamanho do arquivo de uma fonte.

Alguns provedores de fontes podem disponibilizar automaticamente versões diferentes de arquivos de fontes com subconjuntos diferentes. Por exemplo, Google Fonts faz isso por padrão:

/* devanagari */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJbecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
}
/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJnecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Ao migrar para a auto-hospedagem, essa é uma otimização que pode ser perdida e levar a arquivos de fonte maiores localmente.

É possível criar subconjuntos de fontes manualmente se o provedor de fontes permitir isso, seja com uma API (o Google Fonts oferece suporte a isso fornecendo um text parâmetro), ou editando manualmente os arquivos de fonte e, em seguida, auto-hospedando. As ferramentas para gerar subconjuntos de fontes incluem subfont e glyphanger.

Sempre confira as licenças de fonte para confirmar se elas permitem subconjuntos e auto-hospedagem.

Usar menos fontes da Web

A fonte mais rápida de disponibilizar é uma fonte que não é solicitada em primeiro lugar. As fontes do sistema e as fontes variáveis são duas maneiras de reduzir o número de fontes da Web usadas no seu site.

Uma fonte do sistema é a fonte padrão usada pela interface do usuário de um dispositivo. As fontes do sistema normalmente variam de acordo com o sistema operacional e a versão. Como a fonte já está instalada, ela não precisa ser baixada. As fontes do sistema podem funcionar muito bem para o corpo do texto.

Para usar a fonte do sistema no CSS, liste system-ui como a família de fontes:

font-family: system-ui

A ideia por trás das fontes variáveis é que uma única fonte variável pode ser usada como substituta de vários arquivos de fonte. As fontes variáveis funcionam definindo um estilo de fonte "padrão" e fornecendo "eixos" para manipular a fonte. Por exemplo, uma fonte variável com um eixo Weight pode ser usada para implementar letras que antes exigiam fontes separadas para claro, normal, negrito e extra negrito.

Nem todos se beneficiam da mudança para fontes variáveis. As fontes variáveis contêm muitos estilos, então normalmente têm tamanhos de arquivo maiores do que fontes não variáveis individuais que contêm apenas um estilo. Os sites que terão a maior melhoria ao usar fontes variáveis são aqueles que usam (e precisam usar) uma variedade de estilos e espessuras de fontes.

Renderização de fontes

Quando se depara com uma fonte da Web que ainda não foi carregada, o navegador enfrenta um dilema: ele deve adiar a renderização do texto até que a fonte da Web chegue? Ou ele deve renderizar o texto em uma fonte de fallback até que a fonte da Web chegue?

Navegadores diferentes processam esse cenário de maneira diferente. Por padrão, os navegadores baseados no Chromium e no Firefox bloqueiam a renderização de texto por até 3 segundos se a fonte da Web associada não tiver sido carregada. O Safari bloqueia a renderização de texto indefinidamente.

Esse comportamento pode ser configurado usando o atributo font-display. Essa escolha pode ter implicações significativas: font-display tem o potencial de afetar o LCP, o FCP e a estabilidade do layout.

Escolher uma estratégia font-display adequada

font-display informa ao navegador como ele deve prosseguir com a renderização de texto quando a fonte da Web associada não tiver sido carregada. Ele é definido por fonte.

@font-face {
  font-family: Roboto, Sans-Serif
  src: url(/fonts/roboto.woff) format('woff'),
  font-display: swap;
}

Há cinco valores possíveis para font-display:

Valor Período de bloqueio Período de troca
Automático Varia de acordo com o navegador Varia de acordo com o navegador
Bloquear 2 a 3 segundos Infinito
Trocar 0ms Infinito
Fallback 100ms 3 segundos
Opcional 100ms Nenhum
  • Período de bloqueio: o período de bloqueio começa quando o navegador solicita uma fonte da Web. Durante o período de bloqueio, se a fonte da Web não estiver disponível, ela será renderizada em uma fonte de fallback invisível e, portanto, o texto ficará invisível para o usuário. Se a fonte não estiver disponível no final do período de bloqueio, ela será renderizada na fonte de fallback.
  • Período de troca: o período de troca vem após o período de bloqueio. Se a fonte da Web ficar disponível durante o período de troca, ela será "trocada".

As estratégias font-display refletem diferentes pontos de vista sobre a compensação entre performance e estética. Assim, é difícil recomendar uma abordagem, já que ela depende de preferências individuais, da importância da fonte da Web para a página e a marca e de como uma fonte que chega tarde pode ser chocante quando trocada.

Para a maioria dos sites, essas são as três estratégias mais aplicáveis, com base na sua principal prioridade:

  • Performance: Use font-display: optional. Essa é a abordagem mais "eficiente": a renderização de texto é atrasada por no máximo 100 ms e há garantia de que não há mudanças de layout relacionadas à troca de fontes. A desvantagem é que a fonte da Web não será usada se chegar tarde.

  • Exibir texto rapidamente e ainda usar uma fonte da Web: use font-display: swap mas disponibilize a fonte cedo o suficiente para que ela não cause uma mudança de layout. A desvantagem dessa opção é a mudança chocante quando a fonte chega tarde.

  • O texto é exibido em uma fonte da Web: use font-display: block, mas disponibilize a fonte cedo o suficiente para minimizar o atraso do texto. A exibição inicial do texto é atrasada. Apesar desse atraso, ele ainda pode causar uma mudança de layout, já que o texto é desenhado de forma invisível e o espaço da fonte de fallback é usado para reservar o espaço. Depois que a fonte da Web é carregada, isso pode exigir um espaço diferente, o que causa uma mudança. Essa pode ser uma mudança menos chocante do que font-display: swap, já que o texto em si não será visto para mudar.

Lembre-se também de que essas duas abordagens podem ser combinadas: por exemplo, use font-display: swap para branding e outros elementos de página visualmente distintos. Use font-display: optional para fontes usadas no corpo do texto.

Fontes de ícones

As estratégias font-display que funcionam bem para fontes da Web convencionais não funcionam tão bem para fontes de ícones. A fonte de fallback para uma fonte de ícones normalmente parece significativamente diferente da fonte de ícones, e os caracteres podem transmitir um significado completamente diferente. Como resultado, as fontes de ícones têm maior probabilidade de causar mudanças de layout significativas.

Além disso, o uso de uma fonte de fallback pode não ser prático. Quando possível, substitua as fontes de ícones por SVGs, que também são melhores para acessibilidade. As versões mais recentes de fontes de ícones populares normalmente oferecem suporte a SVG. Para mais informações sobre como mudar para SVGs, consulte a página do Font Awesome sobre SVG Sprites e nosso Guia de ícones do Material.

Reduzir a mudança entre a fonte de fallback e a fonte da Web

Para reduzir o impacto do CLS, use os size-adjust atributos.

Conclusão

As fontes da Web ainda são um gargalo de performance, mas temos uma variedade cada vez maior de opções para otimizá-las e reduzir esse gargalo o máximo possível.