Remover código não utilizado

Neste codelab, você vai melhorar o desempenho do aplicativo abaixo removendo todas as dependências não utilizadas e desnecessárias.

Captura de tela do aplicativo

Medir

É sempre bom avaliar primeiro o desempenho de um site antes e adicionar otimizações.

  • Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia tela cheia

Vá em frente e clique no seu gatinho favorito! do Firebase O Realtime Database é neste aplicativo, por isso a pontuação é atualizada em tempo real sincronizadas com todas as outras pessoas que usam o aplicativo. 🐈

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Rede.
  3. Marque a caixa de seleção Desativar cache.
  4. Atualize o app.

Tamanho original do pacote de 992 KB

Quase 1 MB de JavaScript está sendo enviado para carregar esse aplicativo simples!

Confira os avisos do projeto no DevTools.

  • Clique na guia Console.
  • Verifique se Warnings está ativado na lista suspensa de níveis ao lado do Entrada Filter.

Filtro de avisos

  • Observe o aviso exibido.

Aviso do console

O Firebase, uma das bibliotecas usadas neste aplicativo, está sendo boa samaritan fornecendo um aviso para que os desenvolvedores saibam que não devem importar seu o pacote inteiro, mas apenas os componentes usados. Em outras palavras, há bibliotecas não utilizadas que podem ser removidas neste aplicativo para que ele seja carregado mais rápido.

Há também casos em que uma biblioteca específica é usada, mas onde pode haver uma alternativa mais simples. O conceito de remover bibliotecas desnecessárias é exploradas posteriormente neste tutorial.

Como analisar o pacote

Há duas dependências principais no aplicativo:

  • Firebase: uma plataforma que oferece serviços úteis para aplicativos iOS, Android ou da Web. Confira o Tempo real Database é usado para armazenar e sincronizar as informações de cada gatinho em tempo real.
  • Moment.js: uma biblioteca de utilitários que facilita processar datas em JavaScript. A data de nascimento de cada gatinho fica armazenada no O banco de dados do Firebase e a moment são usadas para calcular a idade em semanas.

Como apenas duas dependências podem contribuir para um tamanho de pacote de quase 1 MB? Bem, um dos motivos é que qualquer dependência pode, por sua vez, ter as próprias dependências, então há muito mais do que apenas duas se cada profundidade/ramificação da "árvore" de dependência é considerada. É fácil para um aplicativo ficar grande relativamente rápido se muitas dependências estiverem incluídas.

Analise o bundler para ter uma ideia melhor do que está acontecendo. Existem vários diferentes ferramentas criadas pela comunidade que podem ajudar com isso, como webpack-bundle-analyzer

O pacote dessa ferramenta já está incluído no app como um devDependency.

"devDependencies": {
  //...
  "webpack-bundle-analyzer": "^2.13.1"
},

Isso significa que ele pode ser usado diretamente no arquivo de configuração do webpack. Importe-o no início de webpack.config.js:

const path = require("path");

//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

Agora, adicione-o como um plug-in no final do arquivo na matriz plugins:

module.exports = {
  //...
  plugins: [
    //...
    new BundleAnalyzerPlugin()
  ]
};

Quando o aplicativo é recarregado, é exibida uma visualização de todo o em vez do próprio app.

Analisador de pacote do Webpack

Não é tão fofo quanto ver alguns gatinhos favicon, mas incrivelmente útil mesmo assim. Passar o cursor sobre qualquer um dos pacotes mostra o tamanho representado em três maneiras diferentes:

Tamanho da estatística Tamanho antes de qualquer minificação ou compactação.
Tamanho analisado Tamanho do pacote real dentro do pacote após a compilação. A versão 4 do webpack (usado neste aplicativo) reduz os arquivos compilados automaticamente, por isso é menor que a estatística tamanho.
Tamanho Gzip Tamanho do pacote depois de ter sido compactado com a codificação gzip. Isso é abordado em outro guia.

Com a ferramenta webpack-bundle-analyzer, é mais fácil identificar problemas pacotes desnecessários que compõem uma grande porcentagem do pacote.

Como remover pacotes não utilizados

A visualização mostra que o pacote firebase consiste em muito mais do que apenas um banco de dados. Inclui pacotes adicionais, como:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Esses são serviços incríveis fornecidos pelo Firebase (e se referem ao documentação para saber mais), mas nenhum deles está sendo usado no aplicativo, por isso não há não há motivo para importar todas elas.

Reverta as mudanças em webpack.config.js para ver o aplicativo novamente:

  • Remova BundleAnalyzerPlugin da lista de plug-ins:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • Remova a importação não utilizada da parte de cima do arquivo:
const path = require("path");

//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

O aplicativo será carregado normalmente agora. Modifique src/index.js para atualizar o Importações do Firebase.

import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';

Agora, quando o app for recarregado, o aviso do DevTools não será mais exibido. Abrir o O painel Network do DevTools também mostra uma boa redução no tamanho dos pacotes:

Tamanho do pacote reduzido para 480 KB

Mais da metade do tamanho do pacote foi removida. O Firebase oferece várias e oferece aos desenvolvedores a opção de incluir apenas aqueles que necessários. Neste app, apenas o firebase/database foi usado para armazenar e sincronizar todos os dados. A importação firebase/app, que configura a superfície da API para serviços diferentes, é sempre necessário.

Muitas outras bibliotecas conhecidas, como lodash, também permitem que os desenvolvedores importar seletivamente diferentes partes de seus pacotes. Sem fazer muito trabalho, Atualização de importações de bibliotecas em um aplicativo para incluir apenas o que está sendo usado pode resultar em melhorias significativas de desempenho.

Embora o tamanho do pacote tenha sido reduzido um pouco, ainda há mais muito trabalho a ser feito. 😈

Como remover pacotes desnecessários

Ao contrário do Firebase, não é possível importar partes da biblioteca moment como com facilidade, mas talvez possam ser totalmente removidos?

O aniversário de cada gatinho fofo é armazenado no formato Unix (milissegundos) em banco de dados do Firebase.

Datas de nascimento armazenadas no formato Unix

Carimbo de data/hora de uma determinada data e hora, representado pelo número de milissegundos decorridos desde 1o de janeiro de 1970 às 00:00 UTC. Se a fase atual a data e a hora podem ser calculadas no mesmo formato, uma pequena função para encontrar a idade de cada gatinho em semanas provavelmente pode ser construída.

Como sempre, tente não copiar e colar ao acompanhar aqui. Começar em removendo moment das importações em src/index.js.

import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';

Há um listener de eventos do Firebase que processa alterações de valor no banco de dados:

favoritesRef.on("value", (snapshot) => { ... })

Acima disso, adicione uma pequena função para calcular o número de semanas a partir de uma data especificada:

const ageInWeeks = birthDate => {
  const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
  const diff = Math.abs((new Date).getTime() - birthDate);
  return Math.floor(diff / WEEK_IN_MILLISECONDS);
}

Nessa função, a diferença em milissegundos entre a data atual e a hora (new Date).getTime() e a data de nascimento (o argumento birthDate, já em milissegundos) é calculado e dividido pelo número de milissegundos em um uma única semana.

Por fim, todas as instâncias de moment podem ser removidas do listener de eventos. usando esta função:

favoritesRef.on("value", (snapshot) => {
  const { kitties, favorites, names, birthDates } = snapshot.val();
  favoritesScores = favorites;

  kittiesList.innerHTML = kitties.map((kittiePic, index) => {
    const birthday = moment(birthDates[index]);

    return `
      <li>
        <img src=${kittiePic} onclick="favKittie(${index})">
        <div class="extra">
          <div class="details">
            <p class="name">${names[index]}</p>
            <p class="age">${moment().diff(birthday, 'weeks')} weeks old</p>
            <p class="age">${ageInWeeks(birthDates[index])} weeks old</p>
          </div>
          <p class="score">${favorites[index]} ❤</p>
        </div>
      </li>
    `})
});

Agora atualize o aplicativo e confira o painel Network mais uma vez.

Tamanho do pacote reduzido para 225 KB

O tamanho do nosso pacote diminuiu mais da metade novamente!

Conclusão

Com este codelab, você já sabe como analisar um de um pacote específico e por que pode ser tão útil remover recursos pacotes. Antes de começar a otimizar um aplicativo com essa técnica, é importante é importante saber que isso pode ser significativamente mais complexo em aplicativos.

Com relação à remoção de bibliotecas não utilizadas, tente descobrir quais partes de um pacote está sendo usado e quais peças não estão. Para um visual misterioso que parece não estar sendo usado, dê um passo atrás e verifique quais dependências de nível superior podem precisar deles. Tente encontrar uma maneira de separá-las umas das outras.

Na hora de remover bibliotecas desnecessárias, as coisas podem ser um pouco mais complicado. É importante trabalhar em estreita colaboração com sua equipe e ver se há para simplificar partes da base de código. Removendo moment desta aplicativo pode parecer que seria a coisa certa a fazer sempre, mas como se havia fusos horários e localidades diferentes que precisavam ser tratados? Ou e se houvesse manipulações de data mais complicadas? As coisas podem ficar muito é complicado ao manipular e analisar datas/horas, e bibliotecas como moment e date-fns simplificam isso significativamente.

Tudo tem vantagens, e é importante avaliar se vale a pena a complexidade e o esforço para lançar uma solução personalizada, em vez de depender biblioteca de terceiros.