Árvore JavaScript tremendo, como um profissional

Esta é uma tradução de um artigo sobre como otimizar e reduzir o tamanho de um pacote de aplicativos. É bom porque as práticas recomendadas são descritas aqui, dicas que você deve seguir para fazer o trabalho de trishhing e lançar código não utilizado do assembly. Isso será útil para muitos, porque agora todo mundo usa sistemas de montagem nos quais há triagem imediata. Mas, para que funcione corretamente, você deve seguir os princípios descritos abaixo.

imagem

Trichashing se torna a principal técnica quando você precisa reduzir o tamanho do pacote configurável e melhorar o desempenho do aplicativo em JS.

Como o trichashing funciona:

  1. Você declara importações e exportações em cada módulo.
  2. O coletor (Webpack, Rollup ou outro) analisa a árvore de dependência durante a montagem.
  3. O código não utilizado é excluído do pacote final.

imagem
O arquivo do utilitário exporta duas funções,

imagem
mas apenas initializeName é usado, formatName pode ser excluído.

Infelizmente, para a operação correta do trishaking, uma configuração do coletor não é suficiente. Para obter um resultado melhor, é necessário levar em consideração muitos detalhes e garantir que os módulos não foram ignorados durante a otimização.

Por onde começar?


Há um grande número de diretrizes para a criação de trishaking. É melhor começar a mergulhar no tópico com a documentação oficial do Webpack .

Vale ressaltar que, há alguns anos, criei um clichê com uma montagem e trichashing já configurada. Portanto, se você precisar de um ponto de partida para um projeto, meu repositório pode ser um bom exemplo de krakenjs / grumbler .

Este artigo descreve como trabalhar com Webpack, Babel e Terser. No entanto, a maioria dos princípios apresentados funcionará se você usa Webpack, Rollup ou qualquer outra coisa.

Use a sintaxe ES6 para importações e exportações


Usar as importações e exportações do ES6 é o primeiro e mais importante passo para trabalhar com a trichashing.

A maioria das outras implementações do padrão "module", incluindo commonjs e require.js, são não determinísticas durante o processo de construção. Esse recurso não permite que coletores como o Webpack determinem exatamente o que é importado, o que é exportado e, como resultado, qual código pode ser excluído com segurança.

imagem
Opções possíveis ao usar o commonjs.

Ao usar os módulos ES6, as opções de importação e exportação são mais limitadas:

  • Você pode importar e exportar apenas no nível do módulo, e não dentro da função;
  • o nome do módulo pode ser apenas uma sequência estática, não uma variável;
  • tudo o que você importa deve ser exportado para algum lugar.

imagem
Os módulos ES6 possuem semântica e regras de uso mais simples.

Regras simplificadas permitem que os montadores compreendam exatamente o que foi importado e exportado e, como resultado, determinem qual código não é usado.

Não permita que Babel transporte importações e exportações


O primeiro problema que você pode encontrar ao usar o Babel para converter código é a conversão padrão dos módulos ES6 para commonjs. Isso evita que o coletor otimize o código e jogue demais.

Felizmente, na configuração do Babel, há uma maneira fácil de desativar a transpilação de módulos .

Depois que você fizer isso, o coletor poderá assumir a transpilação de importações e exportações.

Torne suas exportações atômicas


O Webpack normalmente deixa as exportações intactas nos seguintes casos:

  • ;
  • ;
  • .

Essas exportações serão totalmente incluídas no pacote ou completamente removidas. Portanto, no final, você pode acabar com um pacote contendo o código que nunca será usado.

imagem
Ambas as funções serão incluídas no pacote, mesmo que apenas uma seja usada.

imagem
E aqui a classe será totalmente adicionada à montagem.

Tente manter suas exportações o mais pequenas e simples possível.

imagem
Somente a função que será usada entrará no pacote final.

A implementação desse aviso permite que o coletor jogue mais código devido ao fato de que agora durante o processo de montagem você pode rastrear qual função foi importada e usada e qual não foi.

Essa dica também ajuda a escrever código em um estilo mais funcional e reutilizável e a evitar o uso de classes onde isso não se justifica.

Se você estiver interessado em programação funcional, confira este artigo .

Evite efeitos colaterais no nível do módulo


Ao escrever módulos, muitas pessoas perdem um fator importante, mas muito insidioso - a influência dos efeitos colaterais.

imagem
O Webpack não entende o que o window.memoize faz e, portanto, não pode executar esta função.

Observe que o exemplo acima window.memoizeserá chamado no momento da importação do módulo.

Como o Webpack vê:

  • ok, uma função de adição pura é criada e exportada aqui - talvez eu possa removê-la se não for usada mais tarde;
  • então window.memoize é chamado, para o qual o add é passado;
  • Não sei o que ela está fazendo window.memoize, mas sei que ela provavelmente chamará adicionar e criará um efeito colateral.
  • por segurança, deixarei a função add no pacote, mesmo que ninguém mais a use .

Na realidade, temos certeza de que window.memoizeé uma função pura que não cria efeitos colaterais e acrescenta chamadas se alguém a usar memoizedAdd.

Mas o Webpack não sabe disso e, por uma questão de paz, adiciona a função add ao pacote final.

Para ser sincero: as versões mais recentes do Webpack e Terser são extraordinariamente boas na detecção de efeitos colaterais.

imagem
Fornecemos mais informações ao Webpack e obtemos um pacote otimizado.

Agora o coletor tem informações suficientes para análise:

  • chamado aqui memoizeno nível do módulo, isso pode estar cheio de problemas;
  • mas a função memoizeveio da importação do ES6, é necessário examinar a função util.js;
  • de fato, memoize parece uma função pura, não há efeitos colaterais;
  • se ninguém usa a função add, podemos excluí-la com segurança do pacote final.

Quando o Webpack não recebe informações suficientes para tomar uma decisão, ele segue o caminho seguro e sai da função.

Use ferramentas para identificar possíveis problemas de trishaking


Encontrei duas ferramentas para identificar problemas.

A primeira ferramenta é a concatenação de módulos , um plug-in para o Webpack, que permite obter um aumento significativo no desempenho. Tem uma opção de depuração. Vale ressaltar que os fatores que impedem a concatenação e a trituração são os mesmos: por exemplo, efeitos colaterais no nível do módulo. Leve os avisos do plugin a sério, pois qualquer problema potencialmente aumenta o tamanho do pacote.

O segundo é o plug-in para o link https://www.npmjs.com/package/eslint-plugin-tree-shaking . Ainda não o integrei no meu boilerplate, porque não suportava o fluxo quando experimentei. No entanto, ele muito bem identificou problemas com o trichashing.

Tenha cuidado com as bibliotecas


Tente usar bibliotecas otimizadas para trichashing. Se você importar um grande pacote de códigos minimizados, por exemplo jquery.min.js, existe a possibilidade de esse módulo não ser otimizado. É melhor procurar um módulo do qual as funções atômicas possam ser importadas e, para montagem e minificação, usar Webpack ou Rollup.

Às vezes você pode importar uma biblioteca inteira. Por exemplo, ao usar a construção de produção React, você não precisa jogar nada fora - tudo o que está nele já está otimizado.

Se você usar uma biblioteca que exporta funções individuais, por exemplo, lodash, tente importar apenas as funções necessárias e verifique se as outras estão excluídas do pacote final.

Use sinalizadores de construção


O plugin DefinePlugin para Webpack possui um recurso maravilhoso, mas não o mais famoso - a capacidade de influenciar o código que será excluído durante o processo de compilação.

imagem

Se o passarmos __PRODUCTION__: truepara o plug-in, não apenas a chamada de função validateOptions, mas também sua definição será excluída do pacote final .
Isso facilita a criação de pacotes diferentes para desenvolvimento e produção e também ajuda a garantir que o código destinado à depuração não entre em produção.

Iniciar montagem


É muito difícil determinar como o Webpack otimizará um módulo específico.

Portanto, execute a compilação, verifique o pacote final e veja o que acontece. Dê uma olhada no código JavaScript e verifique se não há mais nada que deveria ter sido jogado fora pelo trichashing.

Algo mais?


Se você conhece outras dicas úteis, escreva sobre isso nos comentários.

All Articles