4
votes

Performance d'un module de matériau angulaire partagé pouvant inclure de nombreux modules de composants?

Le guide d'utilisation des composants Angular Material suggère de créer un module partagé pour inclure plusieurs composants. Ma question ici concerne l'utilisation du module partagé.

Module de matériau angulaire partagé

import {MatButtonModule} from '@angular/material/button';
import {MatCheckboxModule} from '@angular/material/checkbox';

@NgModule({
  imports: [MatButtonModule, MatCheckboxModule],
  exports: [MatButtonModule, MatCheckboxModule],
})
export class MyOwnCustomMaterialModule { }

Ce module partagé peut contenir de nombreux modules de composants. Peut-être 50 ou plus. Disons que j'ai importé ce module partagé dans un autre module où il n'a besoin que d'un seul module matériel. Dans de tels cas, y a-t-il une pénalité de performance, par exemple, pour le temps de chargement? Les modules partagés sont-ils mis en cache?


0 commentaires

3 Réponses :


2
votes

Les FAQ de NgModule comprennent les notes suivantes.

Et si j'importe le même module deux fois?

Ce n'est pas un problème. Lorsque trois modules importent tous le module «A», Angular évalue le module «A» une fois, la première fois qu'il le rencontre, et ne le fait plus.

C'est vrai quel que soit le niveau A qui apparaît dans une hiérarchie de NgModules importés. Lorsque le module «B» importe le module «A», le module «C» importe «B» et le module «D» importe [C, B, A], alors «D» déclenche l'évaluation de «C», ce qui déclenche l'évaluation de «B», qui évalue «A». Lorsque Angular atteint le «B» et le «A» dans «D», ils sont déjà mis en cache et prêts à l'emploi .

Angular n'aime pas les NgModules avec des références circulaires, alors ne laissez pas le module 'A' importer le module 'B', qui importe le module 'A'.


Il y a un avantage supplémentaire en termes de performances en incluant uniquement les modules de composants Angular Material nécessaires pour une application spécifique.

L' avis de dépréciation pour Angular Material beta.3 indique:

MatérielModule

MaterialModule (et MaterialRootModule ) ont été marqués comme obsolètes. Nous avons constaté qu'avec l'état actuel des arbres tremblants dans le monde, l'utilisation d'un agrégat NgModule tel que MaterialModule NgModule outils d'éliminer le code des composants qui ne sont pas utilisés.

Afin de garantir que les utilisateurs se retrouvent avec la plus petite taille de code possible, nous abandonnons MaterialModule , qui sera supprimé dans une version ultérieure.

Pour remplacer MaterialModule , les utilisateurs peuvent créer leur propre module "Material" au sein de leur application (par exemple, GmailMaterialModule ) qui importe uniquement l'ensemble des composants réellement utilisés dans l'application.

Ce même conseil s'applique toujours à partir de 2019. Le guide de démarrage du matériau angulaire indique :

Vous pouvez également créer un NgModule distinct qui importe puis réexporte tous les composants de matériau angulaire que vous utiliserez dans votre application . En les exportant à nouveau, d'autres modules peuvent simplement inclure votre CustomMaterialModule partout où des composants Material sont nécessaires et obtenir automatiquement tous les modules Material exportés. Le SharedModule est un bon endroit pour importer / exporter les modules Material à l' SharedModule l' SharedModule .


2 commentaires

Vous faites référence à la note de publication de 2017. Mais j'ai mis le dernier doc de conseils matériels. Donc alors? material.angular.io/guide/getting-started


@Sampath Le guide de démarrage actuel de Angular Material recommande toujours de limiter les modules Component à ceux dont votre application a besoin pour améliorer les performances. Voir la note de la FAQ de NgModule sur les modules mis en cache.



1
votes

J'ai eu la même question il y a quelque temps et j'ai trouvé et mis en signet cet article: Éviter les confusions courantes avec les modules en angulaire , écrit par Max Koretskyi aka Wizard

Mise en cache du module

De temps en temps, une nouvelle question apparaît sur stackoverflow d'un développeur craignant que l' importation d'un module à la fois dans un module paresseux et non paresseux entraîne la duplication du code d'un module au moment de l'exécution . C'est une hypothèse compréhensible. Mais pas besoin de s'inquiéter car tous les chargeurs de modules existants mettent en cache le module qu'ils chargent .

Lorsque SystemJS charge un module, il le met dans le cache. La prochaine fois qu'il y aura une demande pour ce module, il le renvoie du cache et n'exécute pas de demande réseau supplémentaire. C'est le processus qui se produit pour chaque module.

Par exemple, lorsque vous écrivez des composants angulaires, vous importez le décorateur de composants à partir du module angulaire / noyau:

import { Component } from '@angular/core';

Vous référencez le package de nombreuses fois dans l'application. Mais SystemJS ne charge pas le package angular / core à chaque fois. Il le charge une fois et le met en cache. Quelque chose de similaire se produit avec Webpack si vous utilisez angular-cli ou que vous configurez le webpack vous-même. Il inclut le code du module une seule fois dans un bundle et lui donne l'ID. Tous les autres modules importent des symboles de ce module en utilisant cet ID.

Je vous suggère de lire l'article en entier et de prendre des notes personnelles car cela m'a vraiment aidé à dissiper un doute sur l'architecture d'angular. Je pense que c'est vraiment bien écrit et clairement expliqué par lui-même, donc je ne vais pas réinventer la roue et la paraphraser.


Quoi qu'il en soit, un SharedModule est utilisé pour partager des composants, des tuyaux et des directives. Bien que vous soyez peut-être en train d'importer des modules de bibliothèques tierces et de les exporter pour les partager. Essentiellement, vous partagez les composants, les tuyaux et les directives qui sont déclarés dans le module de la bibliothèque tierce (dans ce cas, les modules de Angular Material).

SharedModule est compilé dans main-abcd1234.js , quelque chose comme au milieu de ce journal de compilation:

entrez la description de l'image ici

main-abcd1234.js est chargé au démarrage de l'application. Vous pouvez le vérifier en affichant l'onglet de votre réseau dans le chargement initial de votre application.

Comme vous pouvez le voir, pour mon projet actuel, ce n'est pas vraiment énorme, seulement quelques centaines de kilo-octets. Vous pouvez tester si la "taille de votre application" augmentera, en important le module partagé dans, par exemple, un module X, qui n'utilise qu'un seul composant dans le module partagé et vérifier si la taille du bundle compilé du module X augmentera ou non. Ce ne serait pas le cas.

oh, si vous vous demandez comment mes morceaux sont nommés, vous pouvez définir namedChunks dans angular.json sur true, et exécuter ng serve --prod , afin que vous ne voyiez pas de caractères codés de charabia.

À votre santé!


0 commentaires

1
votes

Arrêter d'utiliser le module de matériau partagé

J'avais pensé de la même manière que les personnes qui ont répondu à cette question avant de tester les performances de la façon dont la majorité des articles Angular le recommandent, mais comme cet article , je suis arrivé à la conclusion ci-dessous:

Arrêter d'utiliser le module de matériau partagé

Comme on peut le voir dans l'article, ce n'est pas une bonne idée d'incorporer tous les modules angulaires dans un module. Le test du résultat est simple comme ABC.

L'autre point important est que le lien mentionné dans d'autres réponses. Par exemple, dans cette mise en route avec le matériau angulaire , il n'est pas recommandé de créer un module pour l'exportation de modules de matériau angulaire pour le moment.


0 commentaires