angularComment optimiser les performances ? L'article suivant vous donnera une introduction approfondie à la solution d'optimisation des performances d'Angular : la détection des changements. J'espère qu'il vous sera utile !
Angular能 Optimisation des performances - Détection des changements
La cause première est la suivante : l'exécution de JavaScript et le rendu des pages dans le navigateur se bloquent mutuellement
.
En observant le panneau FPS, nous pouvons facilement surveiller la fluidité de la page actuelle
根因在于:浏览器中的 JavaScript 执行和页面渲染会相互阻塞
。
在 Chrome 的 devtools 中我们可以执行 Cmd+Shift+P 输入 show fps 来快速打开 fps 面板,如下图所示:
通过观察 FPS 面板,我们可以很方便的对当前页面的流畅度进行监控
1 影响页面性能的因素
页面交互是否流畅,在于页面响应是否流畅,而页面响应其本质上就是把页面状态的变更重新渲染到页面上的过程。
页面响应过程大致如下:
一般情况Event Handler事件处理逻辑不会消耗太多时间,所以影响angular性能的因素主要在于异步事件触发
和变更检测
1 Facteurs de performance de la page d'impact 交Que l'interaction avec la page soit fluide dépend de la fluidité de la réponse de la page, et la
réponse de la pagerevient essentiellement à restituer le changement de statut de la page sur la page.
Le processus de réponse de la page est à peu près le suivant :
Généralement, la logique de traitement des événements du gestionnaire d'événements ne consomme pas trop de temps, donc les facteurs qui affectent les performances angulaires résident principalement dans le déclenchement d'événements asynchrones
et la détection de changement.
.
Généralement, la logique de traitement des événements du gestionnaire d'événements ne consomme pas trop de temps, de sorte que les facteurs qui affectent les performances d'Angular résident principalement dans le déclenchement d'événements asynchrones et la détection des changements.
Pour Angular, le processus de rendu de page est le processus de détection des changements. On peut comprendre que la détection des changements d'Angular doit être terminée dans un délai de 16,6 ms pour éviter la perte et le décalage du cadre de page. Vous pouvez optimiser les performances de réponse de la page sous les trois aspects suivants. (1) Pour l'étape de déclenchement d'événements, vous pouvez
réduire le déclenchement d'événements asynchronespour réduire le nombre global de détections de changements et de nouveau rendu ;
(2) Pour l'étape logique d'exécution du gestionnaire d'événements, le temps d'exécution peut être réduit en optimisant la logique de code complexe (3) Pour l'étape de liaison des données de détection de détection de changement et de mise à jour du DOM, la détection de changement et les données du modèle ; peut être réduit Le nombre de calculs pour réduire le temps de rendu ;
Pour (2) Gestionnaire d'événements, des problèmes spécifiques doivent être analysés en détail sans discussion. Principalement optimiser pour (1) (3)2
Optimisation. plan
2.1 Réduire le déclenchement d'événements asynchrones
Dans le mode de détection de changement par défaut d'Angular, les événements asynchrones déclencheront la détection de changement global. Par conséquent, réduisant le déclenchement de. les événements asynchrones amélioreront considérablement les performances d'Angular. Les événements asynchrones incluent l'incident Macro Task (macro mission) et l'événement micro-tâche Micro Task
L'optimisation des événements asynchrones est principalement destinée à la surveillance des événements de Document. Par exemple, click, mouseup, mousemove... et autres événements d'écoute sur le document. : Scénario d'événement de supervision : 事 Renderer2.Listen (documen, ...) Fromevent (Document, ...) Document.adDeventristener (…) 🎜🎜 L'événement de surveillance DOM doit être supprimé lorsque vous n'avez pas besoin d'être déclenché . 🎜Exemple : commande de boîte d'invite [pop]
Scénarios d'utilisation : filtrage des colonnes d'un tableau, clic ailleurs que sur l'icône, ou défilement de page, masquage de la boîte contextuelle de filtrage des colonnes
L'approche précédente consistait à surveiller directement l'événement de clic du document et événement de défilement, cela présente l'inconvénient que la boîte de dialogue ne s'affiche pas, mais il y a toujours un événement d'écoute, ce qui est très déraisonnable.案 Solution raisonnable : lorsque l'invite s'affiche, surveillez les événements de clic et de défilement et supprimez l'incident de surveillance lorsqu'il est masqué.
Pour les événements d'écoute DOM fréquemment déclenchés, vous pouvez utiliser les opérateurs rjx pour optimiser les événements. Veuillez vous référer à
Rjx Operatorpour plus de détails. Marbres RxJS.
2.2 Détection des changementsQu'est-ce que la détection des changements ?
Pour comprendre la détection des changements, nous pouvons trouver la réponse à partir de l'objectif de la détection des changements. L'objectif de la détection des changements angulaires est de maintenir le modèle (code TypeScript) et le modèle (HTML) synchronisés. Par conséquent, la détection des changements peut être comprise comme :
Lors de la détection des changements de modèle, mettez à jour le modèle (DOM ) . Quel est le processus de détection des changements ?
peut être détecté en effectuant une détection de changement dans l'ordre
de haut en bas, c'est-à-dire effectuer d'abord la détection des changements sur le composant parent, puis sur le composant enfant. Vérifiez d'abord les modifications de données du composant parent, puis mettez à jour le modèle de composant parent, lors de la mise à jour du modèle, lorsqu'il rencontre un composant enfant, il mettra à jour la valeur liée au composant enfant, puis entrera dans le composant enfant pour voir si le composant enfant. L'index de la valeur d'entrée @Input a changé.S'il change, marquez le sous-composant comme sale, ce qui nécessite une détection ultérieure des modifications.Après avoir marqué le sous-composant, continuez à mettre à jour le modèle derrière le sous-composant dans le composant parent. ont été mis à jour, apportez des modifications au sous-composant de détection. 2.2.1 Principe de détection des changements angulaires
Dans le mode par défaut de détection des changements par défaut, le principe des événements asynchrones déclenchant la détection des changements d'Angular est qu'angular appelle la méthode tick() d'ApplicationRef à partir du composant racine en utilisant Zone.js pour gérer événements asynchrones. Effectuer une détection des modifications sur les sous-composants. Pendant le processus d'initialisation de l'application Angular, une zone (NgZone) est instanciée, puis toute la logique est exécutée dans l'objet _inner de l'objet.
Zone.js implémente les classes suivantes :
Classe Zone, l'environnement d'exécution des événements JavaScript, comme les threads, ils peuvent transporter certaines données et peuvent avoir des zones parent et enfant.Les opérations utilisateur déclenchent des événements asynchrones (tels que : événements DOM, requêtes d'interface...)
=> La méthode runTask() de zone est appelée dans la fonction EnsureTask(). Dans la méthode runTask, zone appelle le hook de ZoneSpec via l'attribut d'instance _zoneDelegate
=> Les trois hooks de ZoneSpec (onInvokeTask, onInvoke, onHasTask) passent checkStable. () déclenche la notification zone.onMicrotaskEmpty.emit(null)
=> Le composant racine appelle tick() après avoir écouté onMicrotaskEmpty, et la méthode tick appelle detectChanges()
pour démarrer la détection à partir du composant racine
= > ··· refreshView()
appelle executeTemplate()
et la méthode executeTemplate
appelle templateFn()
pour mettre à jour le modèle , la valeur liée au sous-composant (À ce moment, il détectera si la référence d'entrée du sous-composant
@Input() a changé. S'il y a un changement, le sous-composant sera marqué comme
Dirty , c'est-à-dire que ce sous-composant nécessite une détection de changement
)detectChanges()
从根组件开始检测
=> ··· refreshView()
调用executeTemplate()
,executeTemplate
方法中调用templateFn()
更新模板、子组件绑定的值(这时候会去检测子组件的
@Input()输入引用是否改变,如果有改变,会将子组件标记为
Dirty,也就是该子组件需要变更检测
Simplifiez le processus :
déclenchez un événement asynchrone
=> ZoneTask gère l'événement
=> ZoneDelegate appelle le hook de ZoneSpec pour déclencher la notification onMicrotaskEmpty
=> notification et exécute tick(), Commencez à détecter et à mettre à jour dom
Comme le montre le code ci-dessus, 当微任务为空的时候才会触发变更检测
.
Organigramme du principe de détection de changement simple :
Analyse du code source angulaire Référence Zone.js blog.
2.2.2 Solution d'optimisation de la détection des changements
1) Utilisez le mode OnPush
Principe : Réduisez le temps nécessaire à une détection de changement.
La différence entre le mode OnPush et le mode par défaut est la suivante : les événements d'écoute DOM, les événements de minuterie et les promesses ne déclencheront pas la détection des modifications. L'état du composant en mode par défaut est toujours CheckAlways, ce qui signifie que le composant doit être testé à chaque cycle de détection.
En mode OnPush : Les situations suivantes déclencheront la détection de changement
S1, la référence @Input des changements de composant.
Événements liés au DOM du composant, y compris les événements liés au DOM de ses sous-composants, tels que cliquer, soumettre, appuyer sur la souris. @HostListener()
en conséquence, les événements DOM surveillés par dom.
S4. Utilisez les méthodes suivantes pour déclencher manuellement la détection des changements :
ChangeDetectorRef.detectChanges() : Déclenchez la détection des changements du composant actuel et des sous-composants non-OnPush.
ChangeDetectorRef.markForCheck() : marquez la vue actuelle et tous ses ancêtres comme sales, et la détection sera déclenchée lors du prochain cycle de détection.
ApplicationRef.tick() : ne déclenchera pas la détection de changement
2) Utilisez NgZone.runOutsideAngular()
Principe : réduisez le nombre de détections de changement
Écrivez la surveillance globale des événements dom dans le rappel de NgZone.runOutsideAngular() Les événements DOM ne déclencheront pas la détection des changements d'Angular. Si le composant actuel n'a pas été mis à jour, vous pouvez exécuter le hook detectorChanges() de ChangeDetectorRef dans la fonction de rappel pour déclencher manuellement la détection des modifications du composant actuel.
Exemple : composant d'icône dynamique app-icon-react
2.2.3 Méthode de débogage Méthode 1 : Vous pouvez utiliser le plug-in Angular DevTools dans la console du navigateur pour afficher un certain événement DOM. état de détection :Méthode 2 : Vous pouvez saisir directement : ng.profiler.timeChangeDetection() dans la console pour afficher l'heure de détection. Cette méthode permet d'afficher l'heure de détection globale. Blog de référence
Détection des changements angulaires de profilage
2.3 Optimisation du modèle (HTML)
2.3.1 Réduire le rendu DOM : ngFor plus trackBy
À l'aide de l'attribut trackBy de *ngFor, Angular modifie et restitue uniquement les entrées modifiées sans avoir à recharger la liste complète des entrées. Par exemple : scénario de tri de tables. Si trackBy est ajouté à ngFor, seuls les éléments dom de ligne seront déplacés lors du rendu de la table. Si trackBy n'est pas ajouté, les éléments dom de table existants seront d'abord supprimés, puis les éléments dom de ligne seront ajoutés. Évidemment, les performances du déplacement uniquement des éléments dom seront bien meilleures.
2.3.2 Ne pas utiliser de fonctions dans les expressions de modèle
Vous pouvez utiliser un tube à la place, ou vous pouvez utiliser une variable après un calcul manuel. Lorsque des fonctions sont utilisées dans des modèles, que la valeur ait changé ou non, la fonction sera exécutée à chaque fois qu'une détection de changement est effectuée, ce qui affectera les performances.
Scénarios d'utilisation des fonctions dans les modèles :
2.3.3 Réduire l'utilisation de ngFor
L'utilisation de ngFor affectera les performances lorsque la quantité de données est importante.
Exemple :
Utilisez ngFor :
Ne pas utiliser ngFor : performances augmentées d'environ 10 fois
Pour plus de connaissances sur la programmation, veuillez visiter Programmation : Vidéo ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!