Uma fonte da Web "completa", incluindo todas as variantes de estilo (que podem ser desnecessárias) e todos os glifos (que podem não ser usados) pode resultar facilmente em um download de vários megabytes. Neste post, você vai descobrir como otimizar o carregamento de WebFonts para que os visitantes façam o download apenas do que vão usar.
Para resolver o problema de arquivos grandes que contêm todas as variantes,
a regra CSS @font-face
foi projetada especificamente
para permitir que você divida a família de fontes em uma coleção de recursos. Por exemplo, subconjuntos de Unicode e variantes de estilo distintas.
Com essas declarações, o navegador identifica os subconjuntos e variantes úteis e faz o download do conjunto mínimo necessário para renderizar o texto, o que é muito conveniente. No entanto, se você não for cuidadoso, pode também criar um gargalo de desempenho no caminho crítico de renderização e atrasar a renderização do texto.
O comportamento padrão
O carregamento lento de fontes traz uma importante implicação oculta que pode atrasar a renderização de texto. O navegador precisa criar a árvore de renderização, que depende das árvores do DOM e do CSSOM, antes de saber quais recursos de fonte são necessários para renderizar o texto. Como resultado, as solicitações de fontes são atrasadas para bem depois de outros recursos essenciais, e o navegador pode ser impedido de renderizar o texto até que o recurso seja recuperado.
- O navegador solicita o documento HTML.
- O navegador começa a analisar a resposta HTML e a construir o DOM.
- O navegador descobre o CSS, o JS e outros recursos e envia solicitações.
- Depois de receber todo o conteúdo CSS, o navegador constrói o CSSOM e o combina com
a árvore do DOM para construir a árvore de renderização.
- As solicitações de fonte são enviadas depois que a árvore de renderização indica quais variantes da fonte são necessárias para renderizar o texto especificado na página.
- O navegador executa o layout e pinta o conteúdo na tela.
- Se a fonte ainda não estiver disponível, o navegador poderá não renderizar nenhum pixel de texto.
- Depois que a fonte está disponível, o navegador pinta os pixels de texto.
A "corrida" entre a primeira pintura do conteúdo da página, que pode ser feita logo após a criação da árvore de renderização, e a solicitação do recurso de fonte é o que cria o "problema do texto em branco", em que o navegador pode renderizar o layout da página, mas omite qualquer texto.
Ao carregar previamente as WebFonts e usar font-display
para controlar como os navegadores se comportam com fontes indisponíveis,
é possível evitar páginas em branco e mudanças de layout devido ao carregamento de fontes.
Pré-carregar seus recursos de WebFont
Se há alta probabilidade de que sua página precisará de uma WebFont específica hospedada em um URL que você já conheça,
aproveite a priorização de recursos.
O uso de <link rel="preload">
vai acionar uma solicitação para a WebFont no início do caminho crítico de renderização,
sem ter que esperar que o CSSOM seja criado.
Personalizar o atraso na renderização de texto
Embora o pré-carregamento torne mais provável que uma webfont esteja disponível quando o conteúdo de uma página for renderizado,
ele não oferece garantias.
Você ainda precisa considerar como os navegadores se comportam ao renderizar textos que usam uma font-family
que ainda não está disponível.
Na postagem Evitar texto invisível durante o carregamento de fontes, você pode conferir que o comportamento padrão do navegador não é consistente.
No entanto, é possível informar aos navegadores modernos como você quer que eles se comportem usando
font-display
.
Semelhante aos comportamentos de tempo limite de fonte que alguns navegadores implementam,
font-display
segmenta o tempo de vida de um download de fonte em três períodos principais:
- O primeiro é o período de bloqueio da fonte. Durante esse período, se o tipo de fonte não é carregado, qualquer elemento que tentar usá-lo deverá renderizar com um tipo de fonte de fallback invisível. Se o tipo de fonte for carregado com sucesso durante o período de bloqueio, ele será usado normalmente.
- O período de troca da fonte ocorre imediatamente após o período de bloqueio da fonte. Durante esse período, se o tipo de fonte não é carregado, qualquer elemento que tentar usá-lo deverá renderizar com um tipo de fonte de fallback. Se o tipo de fonte for carregado com sucesso durante o período de troca, ele será usado normalmente.
- O período de falha da fonte ocorre imediatamente após o período de troca da fonte. Se o tipo de fonte ainda não estiver carregado quando esse período começar, ele será marcado como uma falha de carregamento, o que causa o uso normal de fonte de fallback. Caso contrário, o tipo de fonte será usado normalmente.
Entender esses períodos significa que você pode usar font-display
para decidir como sua
fonte será renderizada, dependendo do sucesso e do momento do download.
Para trabalhar com a propriedade font-display
, adicione-a às regras @font-face
:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
font-display: auto; /* or block, swap, fallback, optional */
src: local('Awesome Font'),
url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
url('/fonts/awesome-l.woff') format('woff'),
url('/fonts/awesome-l.ttf') format('truetype'),
url('/fonts/awesome-l.eot') format('embedded-opentype');
unicode-range: U+000-5FF; /* Latin glyphs */
}
No momento, font-display
é compatível com o seguinte intervalo de valores:
auto
block
swap
fallback
optional
Para mais informações sobre o pré-carregamento de fontes e a propriedade font-display
, consulte as seguintes postagens:
- Evitar texto invisível durante o carregamento da fonte
- Como controlar a performance da fonte usando font-display
- Impedir a mudança de layout e flashes de texto invisível (FOIT, na sigla em inglês) pré-carregando fontes opcionais
A API Font Loading
Usados juntos, <link rel="preload">
e o CSS font-display
oferecem um ótimo controle sobre o carregamento e a renderização de fontes,
sem acrescentar muita sobrecarga.
Mas se você precisa de personalizações adicionais
e está disposto a lidar com a sobrecarga introduzida pela execução do JavaScript, há outra opção.
A Font Loading API oferece uma interface de script para definir e manipular faces de fontes CSS, controlar o andamento dos downloads e modificar o comportamento padrão de carga retardada. Por exemplo, se você tiver certeza de que uma variante de fonte específica será necessária, ela pode ser definida e o navegador pode ser solicitado para iniciar uma busca imediata do recurso de fonte:
var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});
// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
// apply the font (which may re-render text and cause a page reflow)
// after the font has finished downloading
document.fonts.add(font);
document.body.style.fontFamily = "Awesome Font, serif";
// OR... by default the content is hidden,
// and it's rendered after the font is available
var content = document.getElementById("content");
content.style.visibility = "visible";
// OR... apply your own render strategy here...
});
Além disso, como você pode verificar o status da fonte
(usando o método check()
)
e acompanhar o andamento do download,
você também pode definir uma estratégia personalizada para renderizar texto nas páginas:
- É possível retardar toda a renderização de texto até que a fonte esteja disponível.
- É possível implementar um tempo limite personalizado para cada fonte.
- É possível usar a fonte de fallback para desbloquear a renderização e injetar um novo estilo que usará a fonte desejada depois que ela ficar disponível.
O melhor de tudo é que você também pode combinar as estratégias acima em conteúdos diferentes da página. Por exemplo, atrasar a renderização em algumas seções até que a fonte esteja disponível, usar uma fonte de fallback e renderizar novamente após o download da fonte.
O armazenamento em cache adequado é obrigatório
Normalmente, os recursos de fonte são estáticos e raramente atualizados. Portanto, são ideais para uma expiração longa de max-age. Especifique um cabeçalho ETag condicional e uma política ideal de Cache-Control para todos os recursos de fonte.
Se o aplicativo da Web usa um service worker, a maioria dos casos de uso exige a exibição de recursos de fonte com uma estratégia que prioriza o cache.
Não armazene fontes usando localStorage
ou IndexedDB.
Cada um deles tem seus próprios problemas de desempenho.
O cache HTTP do navegador oferece o melhor e mais robusto mecanismo para fornecer recursos de fonte ao navegador.
Lista de verificação de carregamento de WebFonts
- Personalize o carregamento e a renderização de fontes usando
<link rel="preload">
,font-display
ou a Font Loading API:o comportamento padrão de carregamento lento pode resultar em atraso na renderização de texto. Esses recursos de plataforma da Web permitem modificar esse comportamento para determinadas fontes e especificar estratégias personalizadas de renderização e tempo limite para conteúdos diferentes na página. - Especifique políticas de revalidação e de armazenamento em cache ideal:as fontes são recursos estáticos, raramente atualizados. Verifique se os servidores fornecem um carimbo de data/hora de max-age longo e um token de revalidação para possibilitar a reutilização eficiente de fontes entre páginas distintas. Ao usar um worker de serviço, uma estratégia que prioriza o cache é apropriada.
Testes automatizados para o comportamento de carregamento de WebFont com o Lighthouse
O Lighthouse pode ajudar a automatizar o processo de garantir que você está seguindo as práticas recomendadas de otimização de fontes da Web.
As auditorias a seguir podem ajudar a garantir que suas páginas continuem seguindo as práticas recomendadas de otimização de fontes da Web ao longo do tempo: