Archivio per marzo 2020

Optimizing Angular–minimizzare momentjs & lodash

Partendo dal presupposto che, anche grazie ad Angular, ci siamo liberati dal fardello jQuery, oggi ci sono alcune librerie javascript utili, molto popolari, ma che tendono a occupare più risorse del dovuto, ovvero:

  • Banda (in particolare su 3g 4g)
  • Cpu lato client (che, come minimo, deve parsarsi il js
  • Cpu lato sviluppatore (che deve inserire tutte le dipendenze)

Due di queste librerie sono:

  • Lodash: contiene funzioni utili per lavorare con i tipi/oggetti javascript, gestire correttamente null e undefined…
  • Momentjs: contiene funzioni e oggetti utili a gestire le date in javascript (come dice la pagina ufficiale, parsare, formattare, validare e manipolare le date)

Progetto base e strumenti

Proviamo ora a creare un progetto Angular ”vuoto” (Angular 9 al momento della scrittura), compilare in produzione con le statistiche e analizzare i bundles generati:

npm install -g @angular/cli
ng new EmptyNg --style=css --routing=false
cd EmptyNg
npm install webpack-bundle-analyzer --save-dev
ng build -prod -stat-json
npx webpack-bundle-analyzer .\dist\EmptyNg\stats-es2015.json

Abbiamo anche installato Webpack-bundle-analyzer in quanto ci permette di capire come sono organizzati i bundle generati da webpack (usato internamente da angular/cli). La situazione è la seguente:

image

per un totale di circa 170Kb di javascript (escludendo i file –es5 usati dai browser )

Aggiungiamo Lodash e momentjs

npm install moment
npm install lodash

e usiamoli, altrimenti il l’algoritmo di treeshaking si accorge che non lo usiamo. Modifichiamo così app.component.ts in questo modo:

import * as moment from 'moment';
import * as _ from 'lodash';
…
title = moment().format('YYYY-MM-DD') + _.isNumber(1);

Vediamo cosa è successo:

ng build -prod -stat-json
npx webpack-bundle-analyzer .\dist\EmptyNg\stats-es2015.json

image

Il nostro applicativo è cresciuto drasticamente, il main è passato da 136Kb a 547Kb!
Ma vediamo come risolvere la cosa.

Minimizzare Momentjs

Subito si può osservare che, moment ha una grossa parte che sono le configurazioni delle lingue che difficilmente nel nostro progetto andremo a utilizzare (al più ne useremo alcune). Eliminarle si può, ed è anche semplice, basta utilizzare un plugin webpack apposito e passare la configurazione in fase di build di webpack:

  1. installare il plugin:
    npm install moment-locales-webpack-plugin -save-dev
    
  2. creare un file di config di estensione di webpack (nel mio caso extra-webpack.config.js) e modificarlo quanto segue:
    const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
    module.exports = {
       plugins: [
         new MomentLocalesPlugin({
           localesToKeep: ['it', 'en-gb'] //uniche lingue da tenere
         })
       ]
     };
    
  3. aggiungere la configurazione in fase di build. Per far questo modificare angular.json e aggiungere in
    "customWebpackConfig": {
         "path": "./extra-webpack.config.js",
         "replaceDuplicatePlugins": true
    },
    
  4. Occorre estendere il processo di build utilizzando il paccketto
    npm install @angular-builders/custom-webpack
    
  5. e configurare il builder in angular.json:
    "builder": "@angular-builders/custom-webpack:browser"
    

rebuildiamo e vediamo l’output:

image

e voilà. main.js è passato da 547Kb a circa la metà, 262Kb.

Minimizzare Lodash

Lodash è (quasi) una libreria contenente tante funzioni. L’idea è quella di importare le singole funzioni in base alle nostre necessità. Per farlo, occorre cambiare pacchetto npm (da lodash a lodash-es), e modificare gli import per importare le singole funzioni:

    1. Cambiare pacchetto nuget:
npm uninstall lodash
npm install lodash-es
  1. modificare l’import delle funzioni richieste
import * as _ from 'lodash';
import { isNumber } from 'lodash/isNumber';

Questo il risultato:

image

Come si può vedere, lodash è letteralmente sparito. Ovviamente la dimensione di lodash sarà sempre più grande più funzioni andremo ad utilizzare (spoiler: ma è veramente necessario lodash?

Pubblicità

Lascia un commento