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

A maioria das páginas da Web e aplicativos é composta de muitas partes diferentes. Em vez de enviar todo o JavaScript que compõe o aplicativo assim que a primeira é carregada, dividindo o JavaScript em vários blocos melhora o desempenho da página.

Este codelab mostra como usar a divisão de código para melhorar o desempenho de uma um aplicativo simples que classifica três números.

Uma janela do navegador mostra um aplicativo intitulado Magic Sorter com três campos para inserir números e um botão de classificação.

Medir

Como sempre, é importante primeiro avaliar o desempenho de um site antes para adicionar otimizações.

  1. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia tela cheia
  2. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  3. Clique na guia Rede.
  4. Marque a caixa de seleção Desativar cache.
  5. Atualize o app.

Painel Rede mostrando o pacote JavaScript de 71,2 KB.

71,2 KB de JavaScript apenas para classificar alguns números em um aplicativo simples. What gives?

No código-fonte (src/index.js), a biblioteca lodash é importada e usada neste aplicativo. O Lodash oferece muitas ferramentas úteis mas apenas um método do pacote está sendo usado aqui. Instalar e importar dependências de terceiros inteiras em que apenas uma pequena está sendo utilizada é um erro comum.

Otimizar

Existem algumas maneiras de diminuir o tamanho do pacote:

  1. Escreva um método de classificação personalizado em vez de importar uma biblioteca de terceiros
  2. Usar o método integrado Array.prototype.sort() para classificar numericamente
  3. Só importe o método sortBy do lodash, e não a biblioteca inteira.
  4. Fazer o download do código para classificação somente quando o usuário clicar no botão

As opções 1 e 2 são métodos perfeitamente adequados para reduzir o tamanho do pacote (e faria mais sentido em um aplicativo real). No entanto, essas são não use neste tutorial para ensinar ⏳.

As opções 3 e 4 ajudam a melhorar o desempenho do aplicativo. A as próximas seções deste codelab abordam essas etapas. Como qualquer programação , tente escrever o código você mesmo, em vez de copiar e colar.

Importe apenas o que for necessário

Alguns arquivos precisam ser modificados para importar apenas o único método de lodash. Para começar, substitua essa dependência em package.json:

"lodash": "^4.7.0",

por:

"lodash.sortby": "^4.7.0",

Agora, em src/index.js, importe este módulo específico:

import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";

Atualize como os valores são classificados:

form.addEventListener("submit", e => {
  e.preventDefault();
  const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
  const sortedValues = _.sortBy(values);
  const sortedValues = sortBy(values);

  results.innerHTML = `
    <h2>
      ${sortedValues}
    </h2>
  `
});

Atualize o aplicativo, abra o DevTools e confira o painel Network mais uma vez.

Painel Rede mostrando o pacote JavaScript de 15,2 KB.

Para este aplicativo, o tamanho do pacote foi reduzido em mais de quatro vezes com muito pouco funcionam, mas ainda há espaço para melhorias.

Divisão de código

O webpack é um dos serviços de código aberto pacotes de módulo usados hoje. Em resumo, ele agrupa todos os módulos JavaScript (conforme bem como outros ativos) que compõem um aplicativo da Web em arquivos estáticos que podem ser lido pelo navegador.

O único pacote usado neste aplicativo pode ser dividido em dois blocos:

  • um responsável pelo código que compõe a rota inicial
  • Um bloco secundário que contém nosso código de classificação

Com o uso de importações dinâmicas, um bloco secundário pode ter carregamento lento ou são carregados sob demanda. Neste aplicativo, o código que compõe o bloco pode ser carregado somente quando o usuário pressiona o botão.

Comece removendo a importação de nível superior do método de classificação em src/index.js:

import sortBy from "lodash.sortby";

E importe-o dentro do listener de eventos que é disparado quando o botão é pressionado:

form.addEventListener("submit", e => {
  e.preventDefault();
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

O recurso import() faz parte de um proposta (atualmente em fase de 3 do processo TC39) para incluir o recurso de importar dinamicamente um módulo. O webpack já inclui suporte para isso e segue a mesma sintaxe estabelecida da proposta.

import() retorna uma promessa e, quando ela é resolvida, o objeto selecionado é fornecido, que é dividido em um bloco separado. Após o módulo ser retornado, module.default é usado para fazer referência ao exportação fornecida pela lodash. A promessa é encadeada a outra .then que chama um método sortInput para classificar os três valores de entrada. No fim do ciclo de vida cadeia de promessas, .catch() é usado para processar casos em que a promessa é recusada. devido a um erro.

.

A última coisa que precisa ser feita é escrever o método sortInput na fim do arquivo. Precisa ser uma função que retorna uma função que recebe o método importado de lodash.sortBy. A função aninhada pode classificar os três valores de entrada e atualizar o DOM.

const sortInput = () => {
  return (sortBy) => {
    const values = [
      input1.valueAsNumber,
      input2.valueAsNumber,
      input3.valueAsNumber
    ];
    const sortedValues = sortBy(values);

    results.innerHTML = `
      <h2>
        ${sortedValues}
      </h2>
    `
  };
}

Monitoramento

Atualize o aplicativo uma última vez e fique de olho na Network novamente. Apenas um pequeno pacote inicial é transferido por download assim que o app carrega.

Painel de rede mostrando o pacote JavaScript de 2,7 KB.

Depois que o botão é pressionado para classificar os números de entrada, o bloco que contém o código de classificação é buscado e executado.

Painel de rede mostrando o pacote JavaScript de 2,7 KB seguido por um pacote JavaScript de 13,9 KB.

Observe como os números ainda são classificados.

Conclusão

A divisão de código e o carregamento lento podem ser técnicas extremamente úteis para reduzir o número de o tamanho do pacote inicial de seu aplicativo, e isso pode resultar diretamente carregamento da página muito mais rápido. No entanto, há algumas coisas importantes que precisam antes de incluir essa otimização no seu aplicativo.

interface com carregamento lento

Ao fazer o carregamento lento de módulos específicos de código, é importante considerar como os experiência do usuário seria para usuários com conexões de rede mais fracas. Divisão e carregar um bloco muito grande de código quando um usuário envia uma ação pode torná-lo que o aplicativo tenha parado de funcionar, por isso, considere mostrar uma indicador de carregamento.

Carregamento lento de módulos de nós de terceiros

Essa nem sempre é a melhor abordagem para o carregamento lento de dependências de terceiros no seu e depende do local em que são usados. Geralmente, terceiros as dependências são divididas em um pacote vendor separado que pode ser armazenado em cache, já que mas não são atualizadas com tanta frequência. Leia mais sobre como o SplitChunksPlugin pode: ajudar você a fazer isso.

Carregamento lento com um framework de JavaScript

Muitos frameworks e bibliotecas populares que usam webpack fornecem abstrações para facilitar o carregamento lento do que usar importações dinâmicas no meio da para o aplicativo.

Embora seja útil entender como as importações dinâmicas funcionam, sempre use o método recomendado pelo seu framework/biblioteca para fazer o carregamento lento de módulos específicos.

Pré-carregamento e pré-busca

Sempre que possível, use dicas de navegador como <link rel="preload"> ou <link rel="prefetch"> para tentar carregar módulos críticos mais cedo. O webpack é compatível com as duas dicas usando comentários mágicos na importação. declarações. Isso é explicado com mais detalhes Guia Pré-carregar blocos críticos.

Carregamento lento maior que o código

As imagens podem ser uma parte significativa de um aplicativo. Carregamento lento estão abaixo da dobra ou fora da janela de visualização do dispositivo, podem acelerar um site. Lida mais sobre isso nos Lazysizes (link em inglês).