Pré-carregue recursos essenciais para melhorar a velocidade de carregamento

Quando você abre uma página da Web, o navegador solicita o documento HTML de um servidor, analisa o conteúdo e envia solicitações separadas para todos os recursos referenciados. Como desenvolvedor, você já conhece todos os recursos de que sua página precisa e quais deles são os mais importantes. Use esse conhecimento para solicitar os recursos críticos com antecedência e acelerar o processo de carregamento. Esta postagem explica como fazer isso com <link rel="preload">.

Como funciona a pré-carga

A pré-carga é mais adequada para recursos normalmente descobertos tarde pelo navegador.

Captura de tela do painel de rede do Chrome DevTools.
Neste exemplo, a fonte Pacifico é definida na folha de estilos com uma regra @font-face. O navegador carrega o arquivo de fonte somente depois de concluir o download e a análise da folha de estilo.

Ao pré-carregar um determinado recurso, você informa ao navegador que quer buscá-lo antes que ele o descubra, porque tem certeza de que ele é importante para a página atual.

Captura de tela do painel de rede do Chrome DevTools após a aplicação do pré-carregamento.
Neste exemplo, a fonte Pacifico é pré-carregada, então o download acontece em paralelo com a folha de estilo.

A cadeia de solicitação crítica representa a ordem dos recursos priorizados e buscados pelo navegador. O Lighthouse identifica como descobertos tardiamente os recursos que estão no terceiro nível dessa cadeia. Use a auditoria Solicitações de pré-carregamento de chaves para identificar quais recursos pré-carregar.

Auditoria de pré-carregamento de solicitações de chave do Lighthouse.

Para pré-carregar recursos, adicione uma tag <link> com rel="preload" ao cabeçalho do seu documento HTML:

<link rel="preload" as="script" href="critical.js">

O navegador armazena em cache os recursos pré-carregados para que eles estejam disponíveis imediatamente quando necessário. Ele não executa os scripts nem aplica as folhas de estilo.

As dicas de recursos, por exemplo, preconnect e prefetch, são executadas conforme o navegador achar adequado. Já o preload é obrigatório para o navegador. Os navegadores modernos já são muito bons em priorizar recursos. Por isso, é importante usar o preload com moderação e pré-carregar apenas os recursos mais importantes.

Pré-carregamentos não usados acionam um aviso do console no Chrome, aproximadamente 3 segundos após o evento load.

Aviso do console do Chrome DevTools sobre recursos pré-carregados não utilizados.

Casos de uso

Pré-carregamento de recursos definidos em CSS

As fontes definidas com regras @font-face ou imagens de plano de fundo definidas em arquivos CSS não são descobertas até que o navegador faça o download e analise esses arquivos. O pré-carregamento desses recursos garante que eles sejam buscados antes do download dos arquivos CSS.

Pré-carregamento de arquivos CSS

Se você estiver usando a abordagem de CSS essencial, divida o CSS em duas partes. O CSS essencial necessário para renderizar o conteúdo acima da dobra é inserido no <head> do documento, e o CSS não essencial geralmente é carregado de forma lenta com JavaScript. Aguardar a execução do JavaScript antes de carregar o CSS não essencial pode causar atrasos na renderização quando os usuários rolam a tela. Por isso, é uma boa ideia usar <link rel="preload"> para iniciar o download antes.

Pré-carregamento de arquivos JavaScript

Como os navegadores não executam arquivos pré-carregados, a pré-carga é útil para separar a busca da execução, o que pode melhorar métricas como o tempo até a interação. A pré-carga funciona melhor se você dividir os pacotes JavaScript e pré-carregar apenas os blocos críticos.

Como implementar rel=preload

A maneira mais simples de implementar preload é adicionar uma tag <link> ao <head> do documento:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Fornecer o atributo as ajuda o navegador a definir a prioridade do recurso pré-buscado de acordo com o tipo dele, definir os cabeçalhos corretos e determinar se o recurso já existe no cache. Os valores aceitos para esse atributo incluem: script, style, font, image e outros.

Alguns tipos de recursos, como fontes, são carregados no modo anônimo. Para esses casos, defina o atributo crossorigin com preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Os elementos <link> também aceitam um atributo type, que contém o tipo MIME do recurso vinculado. Os navegadores usam o valor do atributo type para garantir que os recursos sejam pré-carregados apenas se o tipo de arquivo for compatível. Se um navegador não for compatível com o tipo de recurso especificado, ele vai ignorar o <link rel="preload">.

Também é possível pré-carregar qualquer tipo de recurso usando o cabeçalho HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

Um benefício de especificar preload no cabeçalho HTTP é que o navegador não precisa analisar o documento para descobrir isso, o que pode oferecer pequenas melhorias em alguns casos.

Pré-carregamento de módulos JavaScript com webpack

Se você estiver usando um pacote de módulos que cria arquivos de build do seu aplicativo, verifique se ele oferece suporte à injeção de tags de pré-carregamento. Com o webpack versão 4.6.0 ou mais recente, o pré-carregamento é compatível com o uso de comentários mágicos em import():

import(_/* webpackPreload: true */_ "CriticalChunk")

Se você estiver usando uma versão mais antiga do webpack, use um plug-in de terceiros, como preload-webpack-plugin.

Efeitos do pré-carregamento nas Core Web Vitals

O pré-carregamento é uma otimização de desempenho eficiente que afeta a velocidade de carregamento. Essas otimizações podem levar a mudanças nas Métricas essenciais da Web do seu site, e é importante estar ciente delas.

Maior exibição de conteúdo (LCP)

A pré-carga tem um efeito significativo na Maior exibição de conteúdo (LCP) quando se trata de fontes e imagens, já que tanto as imagens quanto os nós de texto podem ser candidatos a LCP. Imagens principais e grandes blocos de texto renderizados usando fontes da Web podem se beneficiar muito de uma dica de pré-carregamento bem posicionada e devem ser usados quando houver oportunidades de entregar esses bits importantes de conteúdo ao usuário mais rapidamente.

No entanto, é preciso ter cuidado ao pré-carregar e fazer outras otimizações. Em especial, evite pré-carregar muitos recursos. Se muitos recursos forem priorizados, na prática, nenhum deles será. Os efeitos do excesso de dicas de pré-carregamento serão especialmente prejudiciais para quem usa redes mais lentas, em que a disputa de largura de banda é mais evidente.

Em vez disso, concentre-se em alguns recursos de alto valor que você sabe que vão se beneficiar de um pré-carregamento bem posicionado. Ao pré-carregar fontes, verifique se você está veiculando fontes no formato WOFF 2.0 para reduzir ao máximo o tempo de carregamento de recursos. Como o WOFF 2.0 tem excelente suporte a navegadores, usar formatos mais antigos, como WOFF 1.0 ou TrueType (TTF), vai atrasar o LCP se o candidato a LCP for um nó de texto.

No caso do LCP e do JavaScript, é importante enviar uma marcação completa do servidor para que o scanner de pré-carregamento do navegador funcione corretamente. Se você estiver oferecendo uma experiência que depende totalmente do JavaScript para renderizar a marcação e não puder enviar HTML renderizado pelo servidor, será vantajoso intervir onde o scanner de pré-carregamento do navegador não consegue e pré-carregar recursos que só seriam descobertos quando o JavaScript terminasse de carregar e executar.

Cumulative Layout Shift (CLS)

O Cumulative Layout Shift (CLS) é uma métrica especialmente importante quando se trata de fontes da Web, e ele tem uma interação significativa com fontes da Web que usam a propriedade font-display do CSS para gerenciar como as fontes são carregadas. Para minimizar as mudanças de layout relacionadas a fontes da Web, considere as seguintes estratégias:

  1. Pré-carregue fontes usando o valor padrão block para font-display. Esse é um equilíbrio delicado. Bloquear a exibição de fontes sem um substituto pode ser considerado um problema de experiência do usuário. Por um lado, o carregamento de fontes com font-display: block; elimina as mudanças de layout relacionadas a fontes da Web. Por outro lado, você ainda quer que essas fontes da Web sejam carregadas o mais rápido possível se forem cruciais para a experiência do usuário. Combinar um pré-carregamento com font-display: block; pode ser um meio termo aceitável.
  2. Pré-carregue fontes usando o valor fallback para font-display. fallback é um compromisso entre swap e block, já que tem um período de bloqueio extremamente curto.
  3. Use o valor optional para font-display sem pré-carregamento. Se uma fonte da Web não for essencial para a experiência do usuário, mas ainda for usada para renderizar uma quantidade significativa de texto da página, considere usar o valor optional. Em condições adversas, o optional vai mostrar o texto da página em uma fonte substituta enquanto carrega a fonte em segundo plano para a próxima navegação. O resultado líquido nessas condições é uma CLS melhorada, já que as fontes do sistema são renderizadas imediatamente, enquanto os carregamentos de página subsequentes carregam a fonte imediatamente sem mudanças de layout.

O CLS é uma métrica difícil de otimizar quando se trata de fontes da Web. Como sempre, faça testes no laboratório, mas confie nos seus dados de campo para determinar se as estratégias de carregamento de fontes estão melhorando ou piorando o CLS.

Interaction to Next Paint (INP)

A Interaction to Next Paint é uma métrica que mede a capacidade de resposta à entrada do usuário. Como a maior parte da interatividade na Web é impulsionada pelo JavaScript, o pré-carregamento do JavaScript que alimenta interações importantes pode ajudar a manter o INP de uma página mais baixo. No entanto, o pré-carregamento de muito JavaScript durante a inicialização pode ter consequências negativas não intencionais se muitos recursos estiverem disputando a largura de banda.

Também é importante ter cuidado com a forma como você faz a divisão de código. A divisão de código é uma excelente otimização para reduzir a quantidade de JavaScript carregado durante a inicialização, mas as interações podem ser atrasadas se dependerem do JavaScript carregado no início da interação. Para compensar isso, é necessário examinar a intenção do usuário e injetar um pré-carregamento para os blocos necessários de JavaScript antes da interação. Um exemplo é o pré-carregamento do JavaScript necessário para validar o conteúdo de um formulário quando qualquer um dos campos dele é selecionado.

Conclusão

Para melhorar a velocidade da página, faça o pré-carregamento de recursos importantes que são descobertos tarde pelo navegador. Pré-carregar tudo seria contraproducente. Portanto, use o preload com moderação e meça o impacto no mundo real.