Reduzir payloads de JavaScript com a divisão de código

Ninguém gosta de esperar. Mais de 50% dos usuários abandonam um site se ele demora mais de três segundos para carregar.

O envio de payloads JavaScript grandes afeta significativamente a velocidade do seu site. Em vez de enviar todo o JavaScript ao usuário assim que a primeira página do aplicativo é carregada, divida o pacote em várias partes e envie apenas o necessário no início.

Por que a divisão de código é benéfica?

A divisão de código é uma técnica que busca minimizar o tempo de inicialização. Quando enviamos menos JavaScript na inicialização, podemos fazer com que os aplicativos sejam mais interativos minimizando o trabalho da linha de execução principal durante esse período crítico.

No caso das Core Web Vitals, reduzir os payloads de JavaScript baixados na inicialização contribui para melhorar os tempos de Interaction to Next Paint (INP). O raciocínio por trás disso é que, ao liberar a linha de execução principal, o aplicativo pode responder às entradas do usuário mais rapidamente, reduzindo os custos de inicialização relacionados à análise, compilação e execução do JavaScript.

Dependendo da arquitetura do seu site, principalmente se ele depende muito da renderização do lado do cliente, reduzir o tamanho dos payloads de JavaScript responsáveis pela renderização da marcação pode melhorar os tempos de Largest Contentful Paint (LCP). Isso pode ocorrer quando o recurso de LCP é descoberto com atraso pelo navegador até que a marcação do lado do cliente seja concluída ou quando a linha de execução principal está muito ocupada para renderizar esse elemento de LCP. Ambos os cenários podem atrasar o tempo de LCP da página.

Medir

O Lighthouse mostra uma auditoria com falha quando uma quantidade significativa de tempo é usada para executar todo o JavaScript em uma página.

Uma auditoria do Lighthouse com falha mostrando que os scripts estão demorando muito para ser executados.

Divida o pacote JavaScript para enviar apenas o código necessário para a rota inicial quando o usuário carregar um aplicativo. Isso minimiza a quantidade de script que precisa ser analisada e compilada, o que resulta em tempos de carregamento da página mais rápidos.

Bundlers de módulo conhecidos, como webpack, Parcel e Rollup, permitem dividir os bundles usando importações dinâmicas. Por exemplo, considere o snippet de código abaixo, que mostra um exemplo de um método someFunction que é acionado quando um formulário é enviado.

import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  // uses moduleA
}

Aqui, someFunction usa um módulo importado de uma biblioteca específica. Se esse módulo não estiver sendo usado em outro lugar, o bloco de código poderá ser modificado para usar uma importação dinâmica para buscá-lo somente quando o formulário for enviado pelo usuário.

form.addEventListener("submit", e => {
  e.preventDefault();
  import('library.moduleA')
    .then(module => module.default) // using the default export
    .then(() => someFunction())
    .catch(handleError());
});

const someFunction = () => {
    // uses moduleA
}

O código que compõe o módulo não é incluído no pacote inicial e agora é carregado de forma lenta ou fornecido ao usuário somente quando necessário após o envio do formulário. Para melhorar ainda mais a performance da página, pré-carregue os blocos críticos para priorizá-los e buscá-los mais rapidamente.

Embora o snippet de código anterior seja um exemplo simples, o carregamento lento de dependências de terceiros não é um padrão comum em aplicativos maiores. Normalmente, as dependências de terceiros são divididas em um pacote de fornecedor separado que pode ser armazenado em cache, já que elas não são atualizadas com frequência. Leia mais sobre como o SplitChunksPlugin pode ajudar você a fazer isso.

A divisão no nível da rota ou do componente ao usar uma framework do lado do cliente é uma abordagem mais simples para o carregamento lento de diferentes partes do aplicativo. Muitos frameworks conhecidos que usam o webpack oferecem abstrações para facilitar o carregamento lento em vez de mergulhar nas configurações.