Come ridurre la dimensione del pacchetto prod?


135

Ho una semplice app, inizializzata da angular-cli.

Visualizza alcune pagine relative a 3 percorsi. Ho 3 componenti. In una di queste pagine utilizzo lodashi moduli HTTP Angular 2 per ottenere alcuni dati (usando RxJS Observable,map e subscribe). Visualizzo questi elementi usando un semplice *ngFor.

Ma, nonostante la mia app sia davvero semplice, ottengo un pacchetto di pacchetti e mappe enormi (secondo me). Non parlo delle versioni di gzip ma delle dimensioni prima di gzipping. Questa domanda è solo una richiesta di raccomandazioni generali.

Alcuni risultati dei test:

costruire

Hash: 8efac7d6208adb8641c1 Tempo: 10129ms chunk {0} main.bundle.js, main.bundle.map (main) 18,7 kB {3} [iniziale] [reso]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [iniziale] [rendering]

chunk {2} scripts.bundle.js, scripts.bundle.map (script) 128 kB {4} [iniziale] [reso]

chunk {3} vendor.bundle.js, vendor.bundle.map (fornitore) 3.96 MB [iniziale] [rendering]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 byte [entry] [rendering]

Aspetta: pacchetto bundle da 10 MB per un'app così semplice?

di build --prod

Hash: 09a5f095e33b2980e7cc Time: 23455ms chunk {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18.3 kB {3} [iniziale] [reso]

chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 kB {4} [iniziale] [rendering]

chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (script) 128 kB {4} [iniziale] [reso]

chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (fornitore) 3.96 MB [iniziale] [rendering]

chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 byte [entry] [reso]

Aspetta di nuovo: una dimensione del pacchetto del fornitore simile per prod?

ng build --prod --aot

Hash: 517e4425ff872bbe3e5b Tempo: pezzo 22856ms {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [iniziale] [reso]

chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (stili) 154 kB {4} [iniziale] [reso]

chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (script) 128 kB {4} [iniziale] [reso]

chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (fornitore) 2,75 MB [iniziale] [reso]

chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 byte [entry] [reso]

ng build --aot

Hash: 040cc91df4df5ffc3c3f Tempo: 11011ms chunk {0} main.bundle.js, main.bundle.map (main) 130 kB {3} [iniziale] [reso]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [iniziale] [rendering]

chunk {2} scripts.bundle.js, scripts.bundle.map (script) 128 kB {4} [iniziale] [reso]

chunk {3} vendor.bundle.js, vendor.bundle.map (fornitore) 2,75 MB [iniziale] [rendering]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 byte [entry] [rendering]

Quindi alcune domande per distribuire la mia app su prod:

  • Perché i pacchetti di fornitori sono così enormi?
  • L'agitazione dell'albero è utilizzata correttamente angular-cli?
  • Come migliorare questa dimensione del pacchetto?
  • I file .map sono richiesti?
  • Le funzionalità di test sono incluse nei bundle? Non ho bisogno di loro in prod.
  • Domanda generica: quali sono gli strumenti raccomandati per il confezionamento di prodotti? Forse angular-cli(utilizzando Webpack in background) non è l'opzione migliore? Possiamo fare di meglio?

Ho cercato molte discussioni su Stack Overflow, ma non ho trovato alcuna domanda generica.


Per ulteriori informazioni sull'ottimizzazione dell'app
angular

1
Ma non credo che dovremmo preoccuparci di tanto, l'angular-cli si evolverà e le cose andranno sempre meglio. Se hai bisogno di alcune funzionalità che angular-cli non ha, basta inviare un problema nel loro repository: github.com/angular/angular-cli
Timathon

mentre penso che @Timathon abbia ragione in qualche modo, se qualcuno sta provando a distribuire Angular2 in produzione dovrebbe preoccuparsi delle dimensioni dei bundle in quanto ciò influisce direttamente sulle prestazioni dell'app. L'elenco di controllo delle prestazioni angolari è un'ottima risorsa per vedere cosa può essere migliorato. il team angolare sta lavorando per ridurre le dimensioni dei pacchi. Entusiasta di vedere dove va!
Jack Clancy,

Risposte:


73

Aggiornamento febbraio 2020

Dato che questa risposta ha avuto molta trazione, ho pensato che sarebbe meglio aggiornarla con le più recenti ottimizzazioni angolari:

  1. Come ha detto un altro risponditore, ng build --prod --build-optimizer è una buona opzione per le persone che usano meno di Angular v5. Per le versioni più recenti, questo viene fatto per impostazione predefinita conng build --prod
  2. Un'altra opzione è quella di utilizzare il modulo chunking / caricamento lento per dividere meglio l'applicazione in blocchi più piccoli
  3. Il motore di rendering Ivy viene fornito per impostazione predefinita in Angular 9, offre dimensioni del pacchetto migliori
  4. Assicurati che i tuoi agenti di terze parti siano agitabili. Se non stai ancora utilizzando Rxjs v6, dovresti esserlo.
  5. Se tutto il resto fallisce, usa uno strumento come webpack-bundle-analyzer per vedere cosa sta causando il gonfiamento nei tuoi moduli
  6. Controlla se i tuoi file sono compressi con gzip

Alcuni sostengono che l'utilizzo della compilazione AOT può ridurre la dimensione del bundle del fornitore a 250kb. Tuttavia, nell'esempio di BlackHoleGalaxy, usa la compilazione AOT ed è ancora lasciato con una dimensione del bundle del fornitore di 2,75 MB ng build --prod --aot, 10 volte più grande dei 250 KB previsti. Questo non è fuori dalla norma per le applicazioni angular2, anche se si utilizza v4.0. 2.75 MB è ancora troppo grande per chiunque si preoccupi davvero delle prestazioni, specialmente su un dispositivo mobile.

Ci sono alcune cose che puoi fare per aiutare le prestazioni della tua applicazione:

1) AOT & Tree Shaking (angular-cli fa questo fuori dalla scatola). Con Angular 9 AOT è di default in ambiente prod e dev.

2) Utilizzo del rendering angolare Universal AKA lato server (non in cli)

3) Web Workers (di nuovo, non in cli, ma una funzionalità molto richiesta)
vedi: https://github.com/angular/angular-cli/issues/2305

4) Service Workers
vedi: https://github.com/angular/angular-cli/issues/4006

Potresti non aver bisogno di tutti questi in una singola applicazione, ma queste sono alcune delle opzioni attualmente presenti per ottimizzare le prestazioni angolari. Credo / spero che Google sia a conoscenza delle carenze predefinite in termini di prestazioni e piani per migliorarlo in futuro.

Ecco un riferimento che parla più in profondità di alcuni dei concetti che ho menzionato sopra:

https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294


Il mio progetto minimo è di 384 KB, vedi github.com/JCornat/min-angular Sono sicuro che esiste un modo semplice per ottimizzarlo, ma è vicino a 250 KB!
Jacques Cornat,

2
@JacquesCornat sembra buono! Ma la tua app ha un solo componente. La domanda è come gestire le dimensioni dei bundle o le applicazioni più grandi. Spesso AOT non riduce abbastanza le dimensioni del bundle e le persone sono costrette a guardare in altro modo per ottimizzare. Consiglio vivamente a tutti di dare un'occhiata al webpack-bundle-analyzer. Un modo molto utile / semplice per vedere che cosa sta causando il gonfiore
Jack Clancy,

Sfortunatamente, servizi come sw-precacherifiutano di gestire pacchetti di fornitori superiori a 2 MB.

1
@JackClancy "La domanda è come gestire dimensioni di bundle o applicazioni più grandi". No, la sua domanda è "come migliorare questa dimensione del pacchetto?" e sta parlando della sua app minimale con 3 componenti. Comunque, parlando di grandi bundle, usando la configurazione AngularClass / angular-starter, lo stesso del mio repository, la dimensione del mio bundle per le grandi app è passata da 8 MB (4 MB senza file di mappa) a 580 KB.
Jacques Cornat,

1
Grazie, mi hai salvato. --prod ha ridotto le dimensioni dell'app da 6 Mb a 1,2 Mb. Non è ancora perfetto, ma accetta poiché è solo per uso desktop.
Vyacheslav Tsivina,

21

Utilizzare la versione più recente cli angolare e il comando uso accumulo ng --prod --build-ottimizzatore Sarà sicuramente di ridurre le dimensioni di generazione per prod ENV.

Ecco cosa fa l'ottimizzatore di build sotto il cofano:

L'ottimizzatore di build ha due lavori principali. Innanzitutto, siamo in grado di contrassegnare parti della tua applicazione come pure, questo migliora il tremolio dell'albero fornito dagli strumenti esistenti, rimuovendo le parti aggiuntive dell'applicazione che non sono necessarie.

La seconda cosa che fa l'ottimizzatore di build è rimuovere i decoratori angolari dal codice di runtime dell'applicazione. I decoratori vengono utilizzati dal compilatore e non sono necessari in fase di esecuzione e possono essere rimossi. Ognuno di questi lavori riduce le dimensioni dei bundle JavaScript e aumenta la velocità di avvio dell'applicazione per i tuoi utenti.

Nota : un aggiornamento per Angular 5 e ng build --prodversioni successive, si occupa automaticamente del processo precedente :)


1
Per quanto riguarda angular 6 in questo momento, il fornitore è ancora 4 MB per l'installazione solo angolare / materiale e base di fuoco
FindOutIslamNow

Questo è un problema con angolare / materiale, anche io ho affrontato quell'errore. L'agitazione dell'albero non eseguita correttamente è probabilmente la causa principale. Con il nuovo motore di rendering IVY probabilmente sarebbe risolto.
Shubhendu Vaid,

13

Lodash può fornire una porzione di codice bug al tuo pacchetto in base alla modalità di importazione da esso. Per esempio:

// includes the entire package (very large)
import * as _ from 'lodash';

// depending on your buildchain, may still include the entire package
import { flatten } from 'lodash';

// imports only the code needed for `flatten`
import flatten from 'lodash-es/flatten'

Personalmente volevo ancora impronte più piccole dalle mie funzioni di utilità. Ad esempio, flattenpuoi contribuire fino al 1.2Ktuo pacchetto, dopo la minimizzazione. Quindi ho creato una raccolta di funzioni lodash semplificate. La mia implementazione di flattencontributi in giro 50 bytes. Puoi verificarlo qui per vedere se funziona per te: https://github.com/simontonsoftware/micro-dash


1
2 / Ho provato i suggerimenti "loadash-es" dal commento sopra. Riduce la dimensione del mio bundle di 0,08 MB.
Stefdelec,

Non è molto! Hai ancora qualcos'altro che importa alla vecchia maniera? Non otterrai alcun aiuto a meno che tutto non venga importato nel nuovo modo.
Eric Simonton,

Penso di aver sostituito tutto. La dimensione non cambierebbe altrimenti. Ho dato un altro suggerimento qui sotto (cosa gzip) che ci ha davvero aiutato.
Stefdelec,

Interessante. A quanto del tuo bundle sta contribuendo / lodash? (Ad esempio usando source-map-explorer.)
Eric Simonton,

11

In primo luogo, i bundle di fornitori sono enormi semplicemente perché Angular 2 si basa su molte librerie. La dimensione minima per l' app Angular 2 è di circa 500 KB (250 KB in alcuni casi, vedere il post in basso).
L'agitazione dell'albero è utilizzata correttamente da angular-cli.
Non non includere .mapi file, perché utilizzato solo per il debug. Inoltre, se si utilizza il modulo di sostituzione a caldo, rimuoverlo per alleggerire il fornitore.

Per il confezionamento per la produzione, uso personalmente Webpack (e anche angular-cli si affida a esso ), perché puoi davvero configure everythingottimizzarlo o eseguirne il debug.
Se vuoi usarlo Webpack, sono d'accordo che sia un po 'complicato una prima vista, ma vedi tutorial in rete, non rimarrai deluso.
Altrimenti, usa angular-cli, che fa davvero bene il lavoro.

L'uso della compilazione anticipata è obbligatorio per ottimizzare le app e ridurre l'app Angular 2 a 250 KB .

Ecco un repository che ho creato ( github.com/JCornat/min-angular ) per testare le dimensioni minime del bundle angolare e ottengo 384kB . Sono sicuro che esiste un modo semplice per ottimizzarlo.

Parlando di grandi app, usando la configurazione AngularClass / angular-starter , la stessa del repository sopra, le dimensioni del mio bundle per le grandi app (oltre 150 componenti ) sono passate da 8 MB (4 MB senza file di mappe) a 580 KB .


Quale specifica configurazione angolare-starter aiuta a ridurre le dimensioni del fascio? È il webpack.config?
MartinJH,

2
Sì, è la configurazione del webpack che riduce la dimensione del pacchetto.
Jacques Cornat,

Grazie per il chiarimento :)
MartinJH,

8

La seguente soluzione presuppone che tu stia servendo la tua dist / cartella usando nodejs. Utilizzare i seguenti app.js a livello di root

const express = require('express'),http = require('http'),path = require('path'),compression = require('compression');

const app = express();

app.use(express.static(path.join(__dirname, 'dist')));
app.use(compression()) //compressing dist folder 
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
})

const port = process.env.PORT || '4201';
app.set('port', port);

const server = http.createServer(app);
server.listen(port, () => console.log('Running at port ' + port))

Assicurati di installare le dipendenze;

npm install compression --save
npm install express --save;

Ora crea l'app

ng build --prod --build-optimizer

Se vuoi comprimere ulteriormente la build, diciamo riduci 300kb (circa) da, quindi segui il processo seguente;

Crea una cartella chiamata vendorall'interno della srccartella e all'interno della cartella del fornitore crea un file rxjs.ts e incolla il codice sottostante in essa;

export {Subject} from 'rxjs/Subject';
export {Observable} from 'rxjs/Observable';
export {Subscription} from 'rxjs/Subscription';

E quindi aggiungi il seguente nel tsconfig.jsonfile nella tua applicazione angular-cli. Quindi in compilerOptions, aggiungi il seguente json;

"paths": {
      "rxjs": [
        "./vendor/rxjs.ts"
      ]
    }

Questo renderà la tua dimensione di costruzione troppo piccola. Nel mio progetto ho ridotto le dimensioni da 11mb a 1mb. Spero che sia d'aiuto


5

Una cosa che vorrei condividere è il modo in cui le librerie importate aumentano le dimensioni della dist. Avevo importato il pacchetto angular2-moment, mentre potevo eseguire tutta la formattazione dell'ora della data richiesta usando il DatePipe standard esportato da @ angular / common.

Con Angular2-Moment "angular2-moment": "^1.6.0",

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 kB {4} [iniziale] [reso] pezzo {1} main.e7496551a26816427b68.bundle.js (principale) 2.2 MB {3} [iniziale] [reso] chunk {2} styles.056656ed596d26ba0192.bundle.css (stili) 69 byte {4} [iniziale] [reso] pezzo {3} venditore.62c2cfe0ca794a5006d1.bundle.js (fornitore) 3.84 MB [iniziale] [rendering] chunk {4 } inline.0b9c3de53405d705e757.bundle.js (inline) 0 byte [entry] [rendering]

Dopo aver rimosso Angular2-moment e usando invece DatePipe

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 kB {4} [iniziale] [reso] chunk {1} main.f2b62721788695a4655c.bundle.js (principale) 2.2 MB {3} [iniziale] [reso] chunk {2} styles.056656ed596d26ba0192.bundle.css (stili) 69 byte {4} [iniziale] [reso] pezzo {3} vendor.e1de06303258c58c9d01.bundle.js (fornitore) 3.35 MB [iniziale] [rendering] chunk {4 } inline.3ae24861b3637391ba70.bundle.js (inline) 0 byte [entry] [rendering]

Nota che il bundle del fornitore ha ridotto di mezzo Megabyte!

Vale la pena verificare cosa possono fare i pacchetti standard angolari anche se hai già familiarità con una lib esterna.



1

Se hai corso ng build --prod, non avresti dovutovendor file.

Se corro solo ng build- ottengo questi file:

inserisci qui la descrizione dell'immagine

La dimensione totale della cartella è ~ 14 MB. Waat! : D

Ma se corro ng build --prod, ottengo questi file:

inserisci qui la descrizione dell'immagine

La dimensione totale della cartella è 584K.

Uno stesso codice. Ho abilitato Ivy in entrambi i casi. Angolare è 8.2.13.

Quindi - immagino che non hai aggiunto --prodal tuo comando build?


1

Se stai usando Angular 8+ e vuoi ridurre le dimensioni del pacchetto puoi usare Ivy. Ivy è il motore di visualizzazione predefinito in Angular 9 Basta andare su src / tsconfig.app.json e aggiungere il parametro angularCompilerOptions, ad esempio:

{
  "extends": ...,
  "compilerOptions":...,
  "exclude": ...,

/* add this one */ 
  "angularCompilerOptions": {
    "enableIvy": true
  }
}

1

Ciò ha ridotto le dimensioni nel mio caso:

ng build --prod --build-optimizer --optimization.

Per Angular 5+ ng-build --prod lo fa di default. Le dimensioni dopo aver eseguito questo comando sono state ridotte da 1,7 MB a 1,2 MB, ma non abbastanza per il mio scopo di produzione.

Lavoro sulla piattaforma di messaggistica di Facebook e le app di messaggistica devono essere inferiori a 1 MB per funzionare sulla piattaforma di messaggistica. Ho cercato di trovare una soluzione per un efficace scuotimento degli alberi, ma ancora senza fortuna.


1

Funziona al 100% di build --prod --aot --build-optimizer --vendor-chunk = true


0

Ho un'app angolare 5+ con avvio a molla (application.properties 1.3+) con l'aiuto della compressione (link allegato sotto) è stato in grado di ridurre la dimensione di main.bundle.ts da 2,7 MB a 530 KB.

Anche per impostazione predefinita --aot e --build-optimizer sono abilitati con la modalità --prod non è necessario specificarli separatamente.

https://stackoverflow.com/a/28216983/9491345


0

Verifica di avere una configurazione denominata "produzione" per ng build --prod, poiché è una scorciatoia per ng build --configuration = production Nessuna risposta ha risolto il mio problema, perché il problema si trovava proprio davanti allo schermo. Penso che questo potrebbe essere abbastanza comune ... Ho internazionalizzato l'app con i18n rinominando tutte le configurazioni in es. Production-it. Poi ho costruito con ng build --prod supponendo che l'ottimizzazione predefinita sia utilizzata e dovrebbe essere vicina all'ottimale, ma in realtà solo ng build è stata eseguita con conseguente bundle 7mb anziché 250kb.


0

Tratto dai documenti angolari v9 ( https://angular.io/guide/workspace-config#alternate-build-configurations ):

Per impostazione predefinita, viene definita una configurazione di produzione e il comando ng build ha l'opzione --prod che crea utilizzando questa configurazione. La configurazione di produzione imposta le impostazioni predefinite che ottimizzano l'app in vari modi, ad esempio raggruppando i file , riducendo al minimo gli spazi bianchi in eccesso , rimuovendo commenti e codice morto e riscrivendo il codice per utilizzare nomi brevi e criptici ( "minificazione" ).

Inoltre puoi comprimere tutti i tuoi deployable con @ angular-builders / custom-webpack: browser builder dove il tuo webpack.config.js personalizzato si presenta così:

module.exports = {
  entry: {
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash].js'
  },
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: true,
    })
  ]
};

Successivamente dovrai configurare il tuo server web per pubblicare contenuti compressi, ad es. Con nginx devi aggiungere a nginx.conf:

server {
    gzip on;
    gzip_types      text/plain application/xml;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;
    ...
}

Nel mio caso la cartella dist si è ridotta da 25 a 5 mb dopo aver appena usato --prod in ng build e quindi ulteriormente ridotta a 1.5mb dopo la compressione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.