Rimuovi il codice inutilizzato

In questo codelab, migliora le prestazioni della seguente applicazione e rimuovere eventuali dipendenze inutilizzate e non necessarie.

Screenshot dell'app

Misura

È sempre consigliabile misurare il rendimento di un sito web prima di aggiungendo ottimizzazioni.

  • Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi Schermo intero schermo intero.

Vai avanti e fai clic sul tuo gattino preferito! di Firebase Realtime Database è utilizzata in questa applicazione, motivo per cui il punteggio si aggiorna in tempo reale sincronizzati con ogni persona che utilizza l'applicazione. 🐈

  1. Premi "Ctrl+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
  2. Fai clic sulla scheda Rete.
  3. Seleziona la casella di controllo Disabilita cache.
  4. Ricarica l'app.

Dimensione originale del bundle: 992 kB

Per caricare questa semplice applicazione vengono spediti quasi 1 MB di codice JavaScript.

Dai un'occhiata agli avvisi del progetto in DevTools.

  • Fai clic sulla scheda Console.
  • Assicurati che Warnings sia attivato nel menu a discesa dei livelli accanto a Input Filter.

Filtro avvisi

  • Dai un'occhiata all'avviso visualizzato.

Avviso della console

Firebase, che è una delle librerie utilizzate in questa applicazione, è una samaritano, comunicando agli sviluppatori di non importare l'intero pacchetto, ma solo i componenti utilizzati. In altre parole, ci sono librerie inutilizzate che possono essere rimosse in questa applicazione per caricarla più velocemente.

Ci sono anche casi in cui viene utilizzata una particolare libreria, ma in cui potrebbero un'alternativa più semplice. Il concetto di rimozione delle librerie non necessarie è più avanti in questo tutorial.

Analisi del bundle in corso...

L'applicazione ha due dipendenze principali:

  • Firebase: una piattaforma che offre una serie di utili per le applicazioni iOS, Android o web. Ecco il report In tempo reale Database viene utilizzato memorizza e sincronizza le informazioni di ogni gattino in tempo reale.
  • Moment.js: una libreria di utilità che semplifica la gestire le date in JavaScript. La data di nascita di ogni gattino è memorizzata nel database Firebase di cui si utilizza moment per calcolare l'età in settimane.

In che modo solo due dipendenze possono contribuire a una dimensione del bundle di quasi 1 MB? Beh, uno dei motivi è che ogni dipendenza può a sua volta avere una propria delle dipendenze, quindi ce ne sono molto di più di due se per ogni profondità/ramo dipendenza "albero" viene preso in considerazione. Le dimensioni di un'applicazione sono semplici relativamente rapidamente se si includono molte dipendenze.

Analizza il bundler per avere un'idea migliore di ciò che succede. Esistono diverse diversi strumenti creati dalla community che possono essere d'aiuto, come webpack-bundle-analyzer

Il pacchetto per questo strumento è già incluso nell'app come devDependency.

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

Ciò significa che può essere utilizzato direttamente nel file di configurazione webpack. Importalo all'inizio di webpack.config.js:

const path = require("path");

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

Ora aggiungilo come plug-in alla fine del file all'interno dell'array plugins:

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

Quando l'applicazione viene ricaricata, dovresti vedere una visualizzazione dell'intero anziché l'app stessa.

Analizzatore bundle Webpack

Non è carino come vedere alcuni gattini FRIENDS, ma è comunque incredibilmente utile. Se passi il mouse sopra uno dei pacchetti, vengono visualizzate le dimensioni rappresentate in tre in vari modi:

Dimensioni statistiche Dimensioni prima della minimizzazione o della compressione.
Dimensioni analizzate Dimensioni del pacchetto effettivo all'interno del bundle dopo la compilazione. La versione 4 di webpack (utilizzata in questa applicazione) minimizza automaticamente i file compilati, motivo per cui le dimensioni sono inferiori rispetto alle statistiche dimensioni.
Dimensioni compressa con gzip Dimensioni del pacchetto dopo che è stato compresso con la codifica gzip. Questo è trattato in una guida separata.

Con lo strumento webpack-bundle-analyzer, è più facile identificare i pacchetti non necessari che costituiscono una grande percentuale del bundle.

Rimozione dei pacchetti inutilizzati

La visualizzazione mostra che il pacchetto firebase è composto da molti altri di un semplice database. Include pacchetti aggiuntivi quali:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Questi sono tutti fantastici servizi offerti da Firebase (e fai riferimento ai documentazione per saperne di più), ma nessuno di questi viene utilizzato nell'applicazione, quindi non c'è motivo per importarli tutti.

Ripristina le modifiche in webpack.config.js per visualizzare di nuovo l'applicazione:

  • Rimuovi BundleAnalyzerPlugin dall'elenco dei plug-in:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • Ora rimuovi l'importazione inutilizzata dalla parte superiore del file:
const path = require("path");

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

Ora l'applicazione dovrebbe caricarsi normalmente. Modifica src/index.js per aggiornare Importazioni Firebase.

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

Ora, quando l'app viene ricaricata, l'avviso DevTools non viene visualizzato. L'apertura del Il riquadro Rete di DevTools mostra anche una ottima riduzione delle dimensioni dei bundle:

Dimensioni del bundle ridotte a 480 kB

È stata rimossa più della metà delle dimensioni del bundle. Firebase offre diverse soluzioni e offre agli sviluppatori la possibilità di includere solo quelli che sono effettivamente necessaria. In questa applicazione, solo firebase/database è stato utilizzato per archiviare e sincronizzare tutti i dati. L'importazione firebase/app, che configura la superficie API per per ognuno dei diversi servizi è sempre obbligatoria.

Anche molte altre librerie popolari, come lodash, consentono agli sviluppatori importare selettivamente le diverse parti dei pacchetti. Senza fare molto lavoro, aggiornare le importazioni delle librerie in un'applicazione per includere solo ciò che viene utilizzato può portare a miglioramenti significativi delle prestazioni.

Anche se le dimensioni dei bundle sono state notevolmente ridotte, c'è ancora lavoro da fare! 😈

Rimozione dei pacchetti non necessari

A differenza di Firebase, l'importazione di parti della libreria moment non può essere eseguita come facilmente, ma forse può essere rimosso del tutto?

La data di nascita di ogni simpatico gattino viene archiviata in formato Unix (millisecondi) in il database Firebase.

Date di nascita memorizzate in formato Unix

Si tratta del timestamp di una data e un'ora particolari, rappresentate dal numero di di millisecondi trascorsi dal 1° gennaio 1970 alle ore 00:00 UTC. Se lo stato attuale data e ora possono essere calcolate nello stesso formato, una piccola funzione per trovare di ogni gattino in settimane.

Come sempre, cerca di non copiare e incollare mentre procedi qui. Inizia con rimozione di moment dalle importazioni in src/index.js.

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

È presente un listener di eventi Firebase che gestisce le modifiche ai valori nel database:

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

Sopra questo, aggiungi una piccola funzione per calcolare il numero di settimane da un specifica data:

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);
}

In questa funzione, la differenza in millisecondi tra la data corrente e l'ora (new Date).getTime() e la data di nascita (l'argomento birthDate, in millisecondi) viene calcolato e diviso per il numero di millisecondi in una sola settimana.

Infine, tutte le istanze di moment possono essere rimosse nel listener di eventi tramite utilizzando questa funzione:

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>
    `})
});

Ora ricarica l'applicazione e dai un'altra occhiata al riquadro Rete.

Dimensioni del bundle ridotte a 225 kB

Le dimensioni del nostro bundle sono di nuovo ridotte di oltre la metà.

Conclusione

Con questo codelab, dovresti avere una buona comprensione di come analizzare un un bundle specifico e perché può essere così utile rimuovere quelli inutilizzati o non necessari pacchetti. Prima di iniziare a ottimizzare un'applicazione con questa tecnica, è è importante sapere che questo aspetto può essere significativamente più complesso applicazioni.

Per quanto riguarda la rimozione delle librerie inutilizzate, prova a scoprire quali parti di una un bundle in uso e quali parti non lo sono. Per uno sguardo misterioso che sembra non venga usato da nessuna parte, fai un passo indietro e controlla e le dipendenze di primo livello necessarie. Cerca di trovare un modo per disaccoppiandole tra loro.

Per quanto riguarda la rimozione delle librerie non necessarie, il problema può essere posto complicato. È importante lavorare a stretto contatto con il team per vedere se ci sono il potenziale di semplificare parti del codebase. Rimozione di moment in questa potrebbe sembrare la cosa giusta da fare ogni volta, ma se fosse necessario gestire fusi orari e impostazioni internazionali diverse? Oppure: e se ci fossero manipolazioni più complicate della data? Le cose possono diventare molto difficili durante la manipolazione e l'analisi di date/ore e librerie come moment e date-fns la semplificano notevolmente.

Ogni cosa è un compromesso ed è importante valutare se vale la pena la complessità e l'impegno necessari per implementare una soluzione personalizzata invece di affidarsi a una raccolta di terze parti.