JavaScript est une langue très flexible. Nous pouvons écrire divers styles de code comme nous le voulons. Différents styles de code conduiront inévitablement à des différences d'efficacité d'exécution. Au cours du processus de développement, nous sommes exposés à de nombreuses méthodes pour améliorer les performances du code. Trier les problèmes communs et faciles à éviter.
L'efficacité d'exécution de JavaScript
La chaîne de portée, la fermeture, l'héritage du prototype, l'évaluation et d'autres fonctionnalités en JavaScript fournissent diverses fonctions magiques tout en apportant divers problèmes d'efficacité. Si vous l'utilisez négligemment, vous condurez à une exécution inefficace.
1. Importation mondiale
Nous utiliserons certaines variables globales (fenêtre, document, variables globales personnalisées, etc.) pendant le processus de codage. Quiconque connaît la chaîne de portée JavaScript sait que l'accès aux variables globales dans une portée locale nécessite de traverser la couche entière de la chaîne de portée par couche jusqu'à la portée de niveau supérieur, et l'efficacité d'accès des variables locales sera plus rapide et plus élevée. Par conséquent, lors de l'utilisation de certains objets globaux à haute fréquence dans la portée locale, il peut être importé dans la portée locale, par exemple:
La copie de code est la suivante:
// 1. Passer dans le module comme paramètre
(fonction (fenêtre, $) {
var xxx = window.xxx;
$ ("# xxx1"). xxx ();
$ ("# xxx2"). xxx ();
}) (fenêtre, jQuery);
// 2. Stocker des variables locales
fonction(){
var doc = document;
var global = window.global;
}
2. Problèmes d'évaluation et d'évaluation de classe
Nous savons tous qu'Eval peut utiliser une chaîne comme code JS pour l'exécuter et le traiter. On dit que le code exécuté à l'aide d'évaluation est plus de 100 fois plus lent que le code n'utilise pas d'évaluation (je n'ai pas testé l'efficacité spécifique, et ceux qui sont intéressés peuvent le tester)
Le code JavaScript effectuera des opérations de "précompilation" similaires avant l'exécution: d'abord, il créera un objet actif dans l'environnement d'exécution actuel et définira les variables déclarées avec VAR comme propriétés de l'objet actif, mais à l'heure actuelle, les affectations de ces variables sont non définies, et les fonctions définies dans la fonction sont également ajoutées comme des propriétés de l'objet actif, et leurs valeurs sont exactement la définition de la fonction. Cependant, si vous utilisez "EVAL", le code dans "EVAL" (en fait une chaîne) ne peut pas pré-identifier son contexte, ne peut pas être analysé et optimisé à l'avance, c'est-à-dire que les opérations pré-compilées ne peuvent pas être effectuées. Par conséquent, ses performances seront considérablement réduites
En fait, les gens utilisent rarement Eval maintenant. Ce dont je veux parler ici, c'est un scénario de deux types d'évaluation (nouvelle fonction {}, setTimeout, setInterver)
La copie de code est la suivante:
setTImTout ("alert (1)", 1000);
setInterver ("alert (1)", 1000);
(nouvelle fonction ("alert (1)")) ();
Les types d'efficacité d'exécution de code ci-dessus seront relativement faibles, il est donc recommandé de passer directement des méthodes anonymes ou des références à la méthode Settimeout.
3. Une fois la fermeture terminée, la variable qui n'est plus référencée sera publiée.
La copie de code est la suivante:
var f = (function () {
var a = {name: "var3"};
var b = ["var1", "var2"];
var c = document.getElementByTagName ("li");
// **** Autres variables
// *** quelques opérations
var res = fonction () {
alerte (a.name);
}
return res;
}) ()
La valeur de retour de la variable F dans le code ci-dessus est une méthode restée renvoyée dans une fermeture composée d'une fonction d'exécution immédiate. Cette variable conserve des références à toutes les variables (a, b, c, etc.) dans cette fermeture. Par conséquent, ces deux variables résideront toujours dans l'espace mémoire, en particulier la référence à l'élément DOM consommera beaucoup de mémoire. Nous utilisons uniquement la valeur de la variable A en res. Par conséquent, nous pouvons libérer d'autres variables avant le retour de la fermeture.
La copie de code est la suivante:
var f = (function () {
var a = {name: "var3"};
var b = ["var1", "var2"];
var c = document.getElementByTagName ("li");
// **** Autres variables
// *** quelques opérations
// Libérez les variables qui ne sont plus utilisées avant le retour de la fermeture
b = c = null;
var res = fonction () {
alerte (a.name);
}
return res;
}) ()
L'efficacité de JS opérant DOM
Pendant le processus de développement Web, le goulot d'étranglement de l'efficacité d'exécution frontale est souvent sur les opérations DOM. Les opérations DOM sont une chose très consommatrice de performances. Comment pouvons-nous essayer d'économiser des performances pendant les opérations DOM?
1. Réduire la reflux
Qu'est-ce que la reflux?
Lorsque les propriétés de l'élément DOM changent (comme la couleur), le navigateur informera le rendu pour redéfinir l'élément correspondant. Ce processus est appelé Repainte.
Si le changement implique la disposition des éléments (telle que la largeur), le navigateur rejette les attributs d'origine, recalcule et transmet le résultat au rendu pour redéliger les éléments de la page. Ce processus est appelé reflow.
Comment réduire la reflux
Supprimez d'abord l'élément du document, et après avoir terminé la modification, puis remettez l'élément à sa position d'origine (lorsqu'un grand nombre d'opérations de reflux sont effectuées sur un certain élément et ses éléments enfants, les effets des méthodes 1 et 2 seront plus évidents)
Définissez l'affichage de l'élément sur "Aucun", et après avoir terminé la modification, modifiez l'affichage à la valeur d'origine
Définissez la classe de classe lors de la modification des attributs de style multiples au lieu de modifier les attributs de style plusieurs fois (recommandés par certains élèves)
Utilisez le document de document lors de l'ajout de grandes quantités d'éléments à la page
Par exemple
La copie de code est la suivante:
pour (var i = 0; i <100: i ++) {
var child = docuemnt.createelement ("li");
child.innerhtml = "enfant";
document.getElementById ("Parent"). APPENDCHILD (enfant);
}
Lorsque le code nécessite un accès multiple aux informations d'état d'un élément, nous pouvons les stocker temporairement dans une variable lorsque l'état reste inchangé, ce qui peut éviter la surcharge de mémoire causée par un accès multiple au DOM. Un exemple typique est:
Lorsque vous recherchez des éléments DOM, essayez d'éviter de traverser les éléments de la page dans de grandes zones, essayez d'utiliser des sélecteurs précis ou spécifiez un contexte pour affiner la plage de recherche, en prenant JQuery à titre d'exemple
Utilisez moins de sélecteurs de correspondance floue: par exemple $ ("[name * = '_ fix']"), plus utilisez plus de sélecteurs composites tels que ID et rétrécissant progressivement la portée $ ("li.active"), etc.
Spécifiez le contexte: par exemple $ ("# parent .class"), $ (". Classe", $ el) et ainsi de suite
4. Utiliser la délégation des événements
Scénario d'utilisation: une liste avec un grand nombre d'enregistrements. Chaque enregistrement doit être tenu de cliquer sur les événements. Certaines fonctions sont implémentées après avoir cliqué sur la souris. Notre pratique habituelle est de lier à écouter les événements pour chaque disque. Cette pratique conduira à un grand nombre d'écouteurs d'événements sur la page, ce qui est relativement inefficace.
Principe de base: nous savons tous que les événements bouillonneront dans la spécification DOM, c'est-à-dire que les événements de tout élément bouillonneront à l'étape par étape supérieur selon la structure de l'arbre Dom. L'objet d'événement fournit également event.target (srcelement sous IE) pour pointer la source de l'événement, afin que nous puissions trouver l'élément le plus original qui déclenche l'événement même si nous écoutons l'événement sur l'élément parent. Ceci est le principe de base du délégué. Sans plus tarder, l'exemple ci-dessus
Sur la base du principe de surveillance des événements introduits ci-dessus, réécrivons-le.
Bien sûr, nous n'avons pas à juger la source de l'événement à chaque fois, nous pouvons le résumer et le remettre à la classe d'outils pour le terminer. La méthode Delegate () en jQuery implémente cette fonction
La syntaxe est comme $ (sélecteur) .Delegate (ChildSelector, événement, données, fonction), par exemple:
La copie de code est la suivante:
$ ("div"). Delegate ("bouton", "cliquez", fonction () {
$ ("p"). Slidetoggle ();
});
Description du paramètre (cité dans W3School)
Description du paramètre
ChildSelector est requis. Spécifie qu'un ou plusieurs éléments enfants du gestionnaire d'événements à attacher.
Un événement est requis. Spécifie un ou plusieurs événements attachés à l'élément. Séparez plusieurs valeurs d'événements par les espaces. Doit être un événement valide.
Les données sont facultatives. Spécifie les données supplémentaires transmises à la fonction.
fonction requise. Spécifie la fonction qui s'exécute lorsqu'un événement se produit.
Conseils: Un autre avantage de la délégation des événements est que même les événements déclenchés sur les éléments ajoutés dynamiquement après la liaison des événements peuvent être entendus, de sorte que vous n'avez pas à lier des événements à chaque fois que vous ajoutez dynamiquement un élément à la page.