J'ai une application simple, initialisée par angular-cli
.
Il affiche des pages relatives à 3 itinéraires. J'ai 3 composants. Sur l’une de ces pages, j’utilise les modules lodash et Angular2 Http pour obtenir des données (avec Rxjs Observables, map et subscribe). Je montre ces éléments en utilisant un simple ngFor.
Mais, malgré le fait que mon application est vraiment simple, je reçois un paquet énorme et des cartes (à mon avis). Je ne parle pas des versions de gzip mais taille avant gzipping. Cette question est juste une des recommandations générales demander.
Quelques résultats de tests:
ng construire
Hachage: 8efac7d6208adb8641c1 Durée: 10129ms morceau {0} main.bundle.js, main.bundle.map (main) 18,7 Ko {3} [initial] [rendu]
chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendu]
chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 ko {4} [initiale] [rendue]
chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3,96 Mo [initial] [rendu]
chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 octet [entrée] [rendu]
Attendez: Paquet de fournisseur de 10 Mo pour une application aussi simple?
ng build --prod
Hachage: 09a5f095e33b2980e7cc Temps: bloc 23455ms {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (principal) 18,3 kB {3} [initial] [rendu]
chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 kB {4} [initial] [rendu]
chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (scripts) 128 ko {4} [initial] [rendu]
chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (fournisseur) 3,96 Mo [initiale] [rendu]
chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 octet [entrée] [rendu]
Attendez encore: une telle taille de lot fournisseur similaire pour prod?
ng build --prod --aot
Hash: 517e4425ff872bbe3e5b Time: bloc 22856ms {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [initial] [rendu]
chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [initial] [rendu]
chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (scripts) 128 ko {4} [initial] [rendu]
chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (vendor) 2,75 Mo [initiale] [rendu]
chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 octet [entrée] [rendu]
ng build --aot
Hachage: 040cc91df4df5ffc3c3f Heure: bloc 11011ms {0} main.bundle.js, main.bundle.map (main) 130 Ko {3} [initial] [rendu]
chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendu]
chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 ko {4} [initiale] [rendue]
chunk {3} vendor.bundle.js, vendor.bundle.map (fournisseur) 2,75 Mo [initial] [rendu]
chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 octet [entrée] [rendu]
Donc, quelques questions pour le déploiement de mon application sur prod:
J'ai cherché beaucoup de discussions sur Stack Overflow mais je n'ai trouvé aucune question générique.
Mise à jour d'octobre 2018
Cette réponse ayant suscité beaucoup d'intérêt, j'ai pensé qu'il serait préférable de la mettre à jour avec de nouvelles optimisations angulaires:
ng build --prod --build-optimizer
est une bonne option pour les personnes utilisant une version inférieure à Angular v5. Pour les versions plus récentes, ceci est fait par défaut avec ng build --prod
Certaines déclarations prétendent que l'utilisation de la compilation AOT peut réduire la taille de l'ensemble des fournisseurs à 250 Ko. Cependant, dans l’exemple de BlackHoleGalaxy, il utilise la compilation AOT et conserve une taille de lot de 2,75 Mo avec ng build --prod --aot
, 10 fois plus grande que le supposé 250 ko. Ce n'est pas hors de la norme pour les applications angular2, même si vous utilisez v4.0. 2,75 Mo est encore trop volumineux pour quiconque se soucie vraiment de la performance, en particulier sur un appareil mobile.
Vous pouvez effectuer certaines opérations pour améliorer les performances de votre application:
1) AOT & Tree Shaking (angular-cli fait ceci en sortie de boîte)
2) Utilisation de Angular Universal A.K.A. rendu côté serveur (pas en cli)
3) Web Workers (encore une fois, pas en 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 tous ces éléments dans une seule application, mais ce sont quelques-unes des options actuellement disponibles pour optimiser les performances angulaires. Je pense/espère que Google est conscient des insuffisances originales en termes de performances et envisage de les améliorer à l'avenir.
Voici une référence qui décrit plus en détail certains des concepts que j'ai mentionnés ci-dessus:
https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-your-angular2-app-922ce5c1b294
Utilisez la dernière version de cli angulaire et utilisez la commande ng build --prod --build-optimizer Elle va certainement réduire la taille de la construction pour env env.
Voici ce que l'optimiseur de construction fait sous le capot:
L'optimiseur de construction a deux tâches principales. Premièrement, nous sommes en mesure de marquer des parties de votre application comme étant pures, cela améliore l’arborescence fournie par les outils existants, en supprimant des parties supplémentaires de votre application qui ne sont plus nécessaires.
La deuxième chose que l'optimiseur de génération fait consiste à supprimer les décorateurs angulaires du code d'exécution de votre application. Les décorateurs sont utilisés par le compilateur et ne sont pas nécessaires au moment de l’exécution et peuvent être supprimés. Chacune de ces tâches 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, le ng build --prod se charge automatiquement du processus ci-dessus :)
Lodash peut apporter une grande quantité de code à votre paquet en fonction de la manière dont vous l'importez. 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 toujours de plus petites empreintes de pas de mes fonctions utilitaires. Par exemple. flatten
peut contribuer jusqu'à 1.2K
à votre paquet, après réduction. J'ai donc constitué une collection de fonctions lodash simplifiées. Mon implémentation de flatten
contribue autour de 50 bytes
. Vous pouvez vérifier ici pour voir si cela fonctionne pour vous: https://github.com/simontonsoftware/micro-dash
La solution suivante suppose que vous servez 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, construis l'application
ng build --prod --build-optimizer
Si vous voulez compresser davantage la construction, réduisez de 300 kb (environ) de, puis suivez le processus ci-dessous;
Créez un dossier appelévendor
dans le dossiersrc
et dans le dossier du fournisseur. Créez un fichierrxjs.ts
et collez-y le code ci-dessous.
export {Subject} from 'rxjs/Subject';
export {Observable} from 'rxjs/Observable';
export {Subscription} from 'rxjs/Subscription';
Et ajoutez ensuite ce qui suit dans le fichiertsconfig.json
de votre application angular-cli. Puis dans la compilerOptions
, ajoutez le json suivant;
"paths": {
"rxjs": [
"./vendor/rxjs.ts"
]
}
Cela rendra votre taille de construction trop petite. Dans mon projet, j'ai réduit la taille de 11 Mo à 1 Mo . J'espère que cela aide
Une chose que je souhaite partager est la façon dont les bibliothèques importées augmentent la taille de la distribution. J'avais un paquet angular2-moment importé, alors que je pouvais faire tout le formatage date-heure dont j'avais besoin en utilisant le DatePipe standard exporté à partir de @ angular/common.
Avec Angular2-Moment "angular2-moment": "^1.6.0",
chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 Ko {4} [initial] [rendu] chunk {1} main.e7496551a26816427b68.bundle.js (principal) 2,2 Mo {3} [initial] [render] chunk {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 octets {4} chunk {3} vendor.62c2cfe0ca794a5006d1.bundle.js (fournisseur) 3,84 Mo [initiale] [render] chunk {4} inline.0b9c3de53405d705e757.bundle.js (inline) 0 octet [entrée] [rendu]
Après avoir retiré Angular2-moment et utilisé DatePipe à la place
chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 Ko {4} [initial] [rendu] chunk {1} main.f2b62721788695a4655c.bundle.js (principal) 2,2 Mo {3} [initial] [render] chunk {2} styles.056656ed596d26ba0192.bundle.css (styles) 69 octets {4} chunk {3} vendor.e1de06303258c58c9d01.bundle.js (fournisseur) 3,35 Mo [initiale] [render] chunk {4} inline.3ae24861b3637391ba70.bundle.js (inline) 0 octet [entrée] [rendu]
Notez que le paquet du fournisseur a réduit un demi-mégaoctet!
Le fait est que cela vaut la peine de vérifier ce que les paquets standard angulaires peuvent faire même si vous êtes déjà familiarisé avec une bibliothèque externe.
Une autre façon de réduire les offres groupées consiste à servir GZIP au lieu de JS. Nous sommes passés de 2.6mb à 543ko.
Cela a réduit la taille dans mon cas:
ng build --prod --build-optimizer --optimization
Taille après exécution de cette commande réduite de 1,7 Mo à 1,2 Mo, mais pas assez pour mon objectif de production.
Je travaille sur la plate-forme de messagerie Facebook et les applications de messagerie ont besoin de moins de 1 Mo pour fonctionner sur la plate-forme de messagerie. Vous avez essayé de trouver une solution pour secouer efficacement les arbres mais toujours pas de chance.
Si vous utilisez Angular 8+ et que vous souhaitez réduire la taille du paquet, vous pouvez utiliser Ivy. Allez simplement sur src/tsconfig.app.json et ajoutez le paramètre angularCompilerOptions, par exemple:
{
"extends": ...,
"compilerOptions":...,
"exclude": ...,
/* add this one */
"angularCompilerOptions": {
"enableIvy": true
}
}
Vérifiez que vous avez une configuration nommée "production" pour ng build --prod, car c’est un raccourci pour ng build --configuration = production Pas de réponse a résolu mon problème, car le problème se trouvait juste devant le écran. Je pense que cela pourrait être assez courant ... J'ai internationalisé l'application avec i18n en renommant toutes les configurations, par exemple. production-fr. Ensuite, j'ai construit avec ng build --prod en supposant que l'optimisation par défaut est utilisée et qu'elle devrait être proche de l'optimum, mais en fait, ng build a été exécutée, ce qui a abouti à un bundle de 7 Mo au lieu de 250 Ko.
J'ai une application de démarrage à ressort 5 + angulaire (application.properties 1.3+) avec l'aide de la compression (lien ci-dessous) qui a été en mesure de réduire la taille de la taille de main.bundle.ts de 2,7 Mo à 530 Ko.
De plus, par défaut --aot et --build-optimizer sont activés avec le mode --prod, vous n'avez pas besoin de les spécifier séparément.