Angular2 CLI énorme bundle fournisseur: comment améliorer la taille de prod?

J’ai une application simple, initialisée par des angular-cli .

Il affiche des pages relatives à 3 routes. J’ai 3 composants. Sur l’une de ces pages, j’utilise des modules HTTP lodash et Angular2 pour obtenir des données (en utilisant Rxjs Observables, map et subscribe). J’affiche ces éléments en utilisant un simple ngFor.

Mais, malgré le fait que mon application soit très simple, je reçois un ensemble de paquets et de cartes très importants (à mon avis). Je ne parle pas des versions de gzip mais de la taille avant de compresser. Cette question est juste une recommandation générale demander.

Quelques résultats d’essais:

ng construire

Hash: 8efac7d6208adb8641c1 Durée: 10129ms de bloc {0} main.bundle.js, main.bundle.map (main) 18,7 Ko {3} [initiale] [rendu]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 Ko {4} [initial] [rendu]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 Ko {4} [initial] [rendu]

chunk {3} vendor.bundle.js, vendor.bundle.map (fournisseur) 3,96 Mo [initial] [rendu]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 octets [entrée] [rendu]

Attendez: paquet de fournisseur de 10Mb pour une application si simple?

ng build –prod

Hash: 09a5f095e33b2980e7cc Heure: bloc 23455ms {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18,3 Ko {3} [initial] [rendu]

chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 Ko {4} [initiale] [rendu]

chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (scripts) 128 Ko {4} [initiale] [rendu]

chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (fournisseur) 3,96 Mo [initial] [rendu]

chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 octets [entrée] [rendu]

Attendez encore: une taille de paquet fournisseur similaire pour prod?

 ng build --prod --aot 

Hash: 517e4425ff872bbe3e5b Heure: 22856ms chunk {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 Ko {3} [initiale] [rendu]

chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 Ko {4} [initial] [rendu]

chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (scripts) 128 Ko {4} [initial] [rendu]

bloc {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (fournisseur) 2,75 Mo [initial] [rendu]

chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 octets [entrée] [rendu]

 ng build --aot 

Hash: 040cc91df4df5ffc3c3f Durée: 11011ms chunk {0} main.bundle.js, main.bundle.map (main) 130 Ko {3} [initiale] [rendu]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 Ko {4} [initial] [rendu]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 Ko {4} [initial] [rendu]

chunk {3} vendor.bundle.js, vendor.bundle.map (fournisseur) 2,75 Mo [initial] [rendu]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 octets [entrée] [rendu]

Alors quelques questions pour déployer mon application sur prod:

  • Pourquoi les offres groupées sont-elles si importantes?
  • L’arbre secoue-t-il correctement les clivages angulars?
  • comment améliorer cette taille de bundle?
  • Les fichiers .map sont-ils requirejs?
  • Les fonctionnalités de test sont-elles incluses dans les bundles? Je n’ai pas besoin d’eux en prod.
  • Question générique: quels sont les outils recommandés pour emballer pour prod? Peut-être qu’angular-cli (utiliser Webpack en arrière-plan) n’est pas le mieux adapté? Peut-on faire PLUS?

J’ai cherché beaucoup de discussions sur Stack Overflow mais je ne trouve aucune question générique.

Certains prétendent que l’utilisation de la compilation AOT peut réduire la taille des ensembles de fournisseurs à 250kb. Cependant, dans l’exemple de BlackHoleGalaxy, il utilise la compilation AOT et il lui rest une taille de paquet fournisseur de 2,75 Mo avec ng build --prod --aot , 10 fois plus grand que le supposé 250kb. Ceci n’est pas hors norme pour les applications angulars2, même si vous utilisez la version 4.0. 2,75 Mo est encore trop important pour quiconque se soucie vraiment des performances, en particulier sur un appareil mobile.

Vous pouvez faire certaines choses pour améliorer les performances de votre application:

1) AOT & Tree Shaking (l’angular-cli fait cela hors de la boîte)

2) Utilisation du rendu angular Universal AKA côté serveur (pas en cli)

3) Web Workers (encore une fois, pas dans cli, mais une fonctionnalité très demandée)
voir: https://github.com/angular/angular-cli/issues/2305

4) Travailleurs de service
voir: https://github.com/angular/angular-cli/issues/4006

Vous n’avez peut-être pas besoin de toutes ces fonctionnalités dans une seule application, mais ce sont certaines des options actuellement disponibles pour optimiser les performances angulars. Je crois / j’espère que Google est conscient des lacunes en matière de performances et des plans pour améliorer cela à l’avenir.

Voici une référence qui parle plus en profondeur de certains des concepts mentionnés ci-dessus:

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

Utilisez la dernière version de cli angular et utilisez la commande ng build –prod –build-optimizer Cela réduira certainement la taille de construction pour prod env.

C’est ce que fait l’optimiseur de construction sous le capot:

L’optimiseur de construction a deux tâches principales. Premièrement, nous sums en mesure de marquer des parties de votre application comme étant pures, ce qui améliore l’agitation fournie par les outils existants, en supprimant des parties supplémentaires de votre application inutiles.

La deuxième chose que fait l’optimiseur de build est de supprimer les décorateurs angulars du code d’exécution de votre application. Les décorateurs sont utilisés par le compilateur et ne sont pas nécessaires à l’exécution et peuvent être supprimés. Chacun de ces travaux réduit la taille de vos ensembles JavaScript et augmente la vitesse de démarrage de votre application pour vos utilisateurs.

Note : Une mise à jour pour Angular 5, la compilation ng –prod prend automatiquement en charge le processus ci-dessus 🙂

Premièrement, les offres groupées sont énormes car Angular 2 s’appuie sur de nombreuses bibliothèques. La taille minimale pour l’ application Angular 2 est d’environ 500 Ko (250 Ko dans certains cas, voir l’article du bas).
La secousse des arbres est correctement utilisée par les angular-cli .
N’incluez pas les fichiers .map , car utilisés uniquement pour le débogage. De plus, si vous utilisez un module de remplacement à chaud, retirez-le pour alléger le fournisseur.

Pour emballer pour la production, j’utilise personnellement Webpack (et angular-cli y fait également appel ), car vous pouvez configure everything pour l’optimisation ou le débogage.
Si vous voulez utiliser Webpack , je suis d’accord pour dire que c’est un premier sharepoint vue un peu compliqué, mais vous ne serez pas déçu de voir des tutoriels sur le net.
Sinon, utilisez un angular-cli , qui fait très bien votre travail.

L’utilisation de la compilation en avance est indispensable pour optimiser les applications et réduire l’application Angular 2 à 250 Ko .

Voici un repo que j’ai créé ( github.com/JCornat/min-angular ) pour tester une taille de faisceau angular minimale, et j’obtiens 384 Ko . Je suis sûr qu’il existe un moyen simple de l’optimiser.

En parlant de grosses applications, en utilisant la configuration AngularClass / angular-starter , comme dans le repo ci-dessus, la taille de mon bundle pour les grandes applications ( plus de 150 composants ) est passée de 8 Mo (4 Mo sans fichiers cartographiques) à 580 Ko .

Lodash peut append un bloc de code de bogue à votre bundle en fonction de la manière dont vous importez à partir de celui-ci. Par exemple:

 // 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' 

Personnellement, je voulais encore de plus petites empreintes de pas de mes fonctions utilitaires. Par exemple, flatten peut consortingbuer jusqu’à 1.2K à votre bundle, après minimisation. J’ai donc construit une collection de fonctions simplifiées de lodash. Mon implémentation de flatten consortingbue à environ 50 bytes . Vous pouvez le vérifier ici pour voir si cela fonctionne pour vous: https://github.com/simontonsoftware/micro-dash

La solution suivante suppose que vous diffusez votre dossier dist / à l’aide de nodejs. Veuillez utiliser le fichier app.js suivant au niveau racine

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

Assurez-vous d’installer des dépendances;

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

Maintenant, construisez l’application

 ng build --prod --build-optimizer 

Si vous souhaitez compresser davantage la génération, réduisez de 300kb (environ), puis suivez le processus ci-dessous;

Créez un dossier appelé vendor dans le dossier src et dans le dossier du fournisseur, créez un fichier rxjs.ts et collez-y le code ci-dessous;

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

Et puis ajoutez la suite dans le fichier tsconfig.json dans votre application angular-cli. Ensuite, dans le comstackrOptions , ajoutez le json suivant;

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

Cela rendra votre taille de construction beaucoup plus petite. Dans mon projet, j’ai réduit la taille de 11mb à 1mb. J’espère que cela aide

Une chose que je souhaite partager est la façon dont les bibliothèques imscopes augmentent la taille du dist. J’ai eu un paquet angular2-moment importé, alors que je pouvais faire tout le formatage de la date et de l’heure requirejs en utilisant le DatePipe standard exporté depuis @ angular / common.

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

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 Ko {4} [initiale] [rendu] chunk {1} main.e7496551a26816427b68.bundle.js (main) 2,2 Mo bloc {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 octets {4} [initial] [rendu] bloc {3} vendor.62c2cfe0ca794a5006d1.bundle.js (fournisseur) 3,84 Mo [initial] [rendu] bloc {4 } inline.0b9c3de53405d705e757.bundle.js (inline) 0 octets [entrée] [rendu]

Après avoir supprimé Angular2-moment et utilisé DatePipe à la place

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 Ko {4} [initiale] [rendu] bloc {1} main.f2b62721788695a4655c.bundle.js (main) 2,2 Mo {3} bloc {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 octets {4} [initial] [rendu] bloc {3} vendor.e1de06303258c58c9d01.bundle.js (fournisseur) 3,35 Mo [initial] [rendu] bloc {4 } inline.3ae24861b3637391ba70.bundle.js (inline) 0 octets [entrée] [rendu]

Notez que le groupe de fournisseurs a réduit de moitié un mégaoctet!

Il est utile de vérifier quels paquets standard angulars peuvent faire même si vous êtes déjà familiarisé avec une lib externe.

Une autre façon de réduire les offres groupées consiste à servir GZIP au lieu de JS. Nous sums passés de 2.6mb à 543ko.

https://httpd.apache.org/docs/2.4/mod/mod_deflate.html