Maison  >  Article  >  interface Web  >  Résumé des conseils pour améliorer les performances Web de JavaScript

Résumé des conseils pour améliorer les performances Web de JavaScript

伊谢尔伦
伊谢尔伦original
2017-07-20 10:22:031091parcourir

L'optimisation des performances Javascript n'est en aucun cas une technique écrite. L'évolution technique de Nicholas répertorie 10 suggestions pour vous aider à écrire du code JS efficace

1 Définir des variables locales

. Lorsqu'une variable est référencée, JavaScript recherchera la variable dans différents membres de la chaîne de portée. La chaîne de portée fait référence à l'ensemble des variables disponibles qui agissent actuellement sur elle. Elle contient au moins deux parties dans divers navigateurs grand public : l'ensemble des variables locales et l'ensemble des variables globales.

En termes simples, plus le moteur JavaScript recherche en profondeur dans la chaîne de portée, plus l'opération prendra du temps. Le moteur recherche d'abord les variables locales à partir de là, puis les paramètres de fonction, les variables définies localement, et enfin parcourt toutes les variables globales.

Étant donné que les variables locales se trouvent au début de la chaîne, la recherche de variables locales est toujours plus rapide que la recherche de variables globales. Ainsi, lorsque vous souhaitez utiliser une variable globale plus d'une fois, vous devez la définir comme une variable locale, comme ceci :


var blah = document.getElementById('myID'),
blah2 = document.getElementById('myID2');

réécrite comme


var doc = document,
blah = doc.getElementById('myID'),
blah2 = doc.getElementById('myID2');

2. N'utilisez pas l'instruction with()

C'est parce que l'instruction with() sera dans la chaîne de portée Start. en ajoutant des variables supplémentaires. Les variables supplémentaires signifient que lorsqu'il faut accéder à une variable, le moteur JavaScript doit d'abord analyser les variables générées par l'instruction with(), puis les variables locales et enfin les variables globales.
Donc, with() donne essentiellement aux variables locales tous les inconvénients de performances des variables globales, ce qui fait dérailler les plans de performances Javascript.

3. Utilisez les fermetures avec précaution

Bien que vous ne connaissiez peut-être pas encore les « fermetures », vous utilisez peut-être souvent cette technique sans même vous en rendre compte. Les fermetures sont fondamentalement considérées comme nouvelles en JavaScript. Nous utilisons des fermetures lorsque nous définissons une fonction immédiate, telle que :

 document.getElementById('foo').onclick = function(ev) { };

Le problème avec les fermetures est que, par définition, elles contiennent au moins trois objets dans la portée. chaîne : variables de fermeture, variables locales et variables globales. Ces objets supplémentaires entraîneront les problèmes de performances mentionnés dans les suggestions 1 et 2.

Mais je pense que Nicholas ne nous demande pas d'arrêter de manger à cause d'un étouffement. Les fermetures sont toujours très utiles pour améliorer la lisibilité du code, etc., mais n'en abusez pas (surtout dans les boucles).

4. Les attributs d'objet et les éléments de tableau sont plus lents que les variables

En ce qui concerne les données JavaScript, de manière générale, il existe 4 méthodes d'accès : les valeurs numériques, les variables, Propriétés des objets et éléments du tableau. Lorsque l'on considère les optimisations, les nombres et les variables fonctionnent à peu près de la même manière et sont nettement plus rapides que les propriétés d'objet et les éléments de tableau.
Ainsi, lorsque vous référencez une propriété d'objet ou un élément de tableau plusieurs fois, vous pouvez améliorer les performances en définissant une variable. (Cette règle est valable lors de la lecture et de l'écriture de données)
Bien que cette règle soit correcte dans la plupart des cas, Firefox a effectué un travail intéressant en optimisant les index de tableau, ce qui peut rendre ses performances réelles meilleures que celles des variables. Cependant, compte tenu des inconvénients de performances des éléments de tableau sur d'autres navigateurs, vous devriez essayer d'éviter les recherches de tableaux à moins que vous ne développiez réellement pour les performances de Firefox.

5. Ne creusez pas trop profondément dans le tableau

De plus, les programmeurs doivent éviter de creuser trop profondément dans le tableau, car plus vous entrez dans de couches, l'opération la vitesse est plus lente.
En termes simples, les opérations dans les tableaux avec de nombreux niveaux d'imbrication sont lentes car la recherche d'éléments du tableau est lente. Imaginez que si vous opérez sur des éléments de tableau imbriqués sur trois niveaux, vous devez effectuer trois recherches d'éléments de tableau au lieu d'une.
Donc, si vous continuez à référencer foo.bar, vous pouvez améliorer les performances en définissant var bar = foo.bar.

6. Évitez les boucles for-in (et les itérations basées sur les fonctions)

Voici un autre conseil très dogmatique : n'utilisez pas de boucles for-in.
La logique derrière cela est très simple : pour parcourir les éléments d'une collection, vous pouvez utiliser une boucle for ou une boucle do-while au lieu d'une boucle for-in. Une boucle for-in peut non seulement avoir besoin. pour parcourir des éléments de tableau supplémentaires, plus de temps est nécessaire.
Afin d'itérer sur ces éléments, JavaScript doit créer une fonction pour chaque élément. Cette itération basée sur les fonctions entraîne une série de problèmes de performances : les fonctions supplémentaires introduisent le contexte dans lequel l'objet fonction est créé et détruit, ce qui sera en vigueur Des éléments supplémentaires sont ajoutés au sommet de la chaîne de domaines.

7. Combinez les conditions de contrôle et les variables de contrôle lors du bouclage

En matière de performances, le travail à éviter dans les boucles a toujours été un sujet brûlant, car les boucles seront exécutées à plusieurs reprises plusieurs fois. Par conséquent, s’il existe un besoin d’optimisation des performances, l’amélioration la plus évidente des performances peut être obtenue en opérant d’abord sur la boucle.
Une façon d'optimiser une boucle est de combiner les conditions de contrôle et les variables de contrôle lors de la définition de la boucle. Voici un exemple sans les fusionner :

 for ( var x = 0; x < 10; x++ ) {
};

Quand. on ajoute quelque chose à cette boucle, on constate qu'il y a plusieurs opérations qui apparaîtront à chaque itération. Le moteur JavaScript nécessite :

#1:检查 x 是否存在
#2:检查 x 是否小于 0 (译者注:我猜这里是作者的笔误)
#3:使 x 增加 1

然而如果你只是迭代元素中的一些元素,那么你可以使用while循环进行轮转来替代上面这种操作:


var x = 9;
do { } while( x-- );

如果你想更深入地了解循环的性能,Zakas提供了一种高级的循环优化技巧,使用异步进行循环(碉堡了!)

8. 为HTML集合对象定义数组

JavaScript使用了大量的HTML集合对象,比如 document.forms,document.images 等等。通常他们被诸如 getElementsByTagName、getElementByClassName 等方法调用。

由于大量的DOM selection操作,HTML集合对象相当的慢,而且还会带来很多额外的问题。正如DOM标准中所定义的那样:“HTML集合是一个虚拟存在,意味着当底层文档被改变时,它们将自动更新。”这太可怕了!

尽管集合对象看起来跟数组很像,他们在某些地方却区别很大,比如对于特定查询的结果。当对象被访问进行读写时,查询需要重新执行来更新所有与对象相关的组分,比如 length。

HTML集合对象也非常的慢,Nicholas说好像在看球的时候对一个小动作进行60倍速慢放。另外,集合对象也有可能造成死循环,比如下面的例子:


var ps = document.getElementsByTagName(&#39;p&#39;);
 
for (var i=0; i < ps.length; i++ ) {
  var p = document.createElement("p"); 
  document.appendChild(p);
}

这段代码造成了死循环,因为 ps 表示一个实时的HTML集合,并不是你所期望的数组。这种实时的集合在添加 e388a4556c0f65e1904146cc1a846bee 标签时被更新,所以i < p.length 永远都不会结束。

解决这个问题的方法是将这些元素定义成数组,相比只设置 var ps = document.getElementsByTagName(‘p') 稍微有点麻烦,下面是Zakas提供的强制使用数组的代码:


function array(items) {
  try {
    return Array.prototype.concat.call(items);
  } catch (ex) {
 
    var i    = 0,
      len   = items.length,
      result = Array(len);
 
    while (i < len) {
      result[i] = items[i];
      i++;
    }
 
    return result;
  }
}
 
var ps = array( document.getElementsByTagName(&#39;p&#39;) );
 
for (var i=0l i < ps.length; i++ ) {
  var p = document.createElement("p"); 
  document.appendChild(p);
}

9. 不要碰DOM!

不使用DOM是JavaScript优化中另一个很大的话题。经典的例子是添加一系列的列表项:如果你把每个列表项分别加到DOM中,肯定会比一次性加入所有列表项到DOM中要慢。这是因为DOM操作开销很大。
Zakas对这个进行了细致的讲解,解释了由于回流(reflow)的存在,DOM操作是非常消耗资源的。回流通常被理解为浏览器重新选渲染DOM树的处理过程。比如说,如果你用JavaScript语句改变了一个p的宽度,浏览器需要重绘页面来适应变化。
任何时候只要有元素被添加到DOM树或者从DOM树移除,都会引发回流。使用一个非常方便的JavaScript对象可以解决这个问题——documentFragment,我并没有使用过,但是在Steve Souders也表示同意这种做法之后我感觉更加肯定了。
DocumentFragment 基本上是一种浏览器以非可视方式实现的类似文档的片段,非可视化的表现形式带来了很多优点,最主要的是你可以在 documentFragment 中添加任何结点而不会引起浏览器回流。

10. 修改CSS类,而不是样式

你也许听说过:修改CSS类必直接修改样式会更高效。这归结于回流带来的另一个问题:当布局样式发生改变时,会引发回流。
布局样式意味着任何影响改变布局的变化都会强制引起浏览器回流。比如宽度、高度、字号、浮动等。
但是别误会我的意思,CSS类并不会避免回流,但是可以将它的影响最小化。相比每次修改样式都会引起回流,使用CSS类一次修改多个样式,只需要承担一次回流带来的消耗。
因此在修改多个布局样式的时候,使用CSS类来优化性能是明智的选择。另外如果你需要在运行时定义很多歌CSS类,在DOM上添加样式结点也是不错的选择。

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn