L'efficacité d'exécution du code JS affecte souvent directement les performances de la page. Parfois, pour obtenir la même fonction, différents codes JS ont souvent une efficacité très différente. Parfois, cela est simplement dû à nos habitudes d'écriture. Bien sûr, dans les navigateurs avancés. , la plupart d'entre eux nous ont aidé à l'optimiser, mais en Chine, le maléfique IE6 existe toujours en grand nombre, et nous devons y réfléchir. Concernant l'optimisation du code JS, il existe en fait de nombreuses situations, dont certaines ont un impact relativement faible, et d'autres sont plus graves. Dans cet article, j'énumère quelques situations qui, à mon avis, ont un impact sérieux pour votre référence.
1. Épissage de chaînes
L'épissage de chaînes est souvent rencontré dans notre développement, je le mets donc en premier. Nous sommes souvent habitués à utiliser directement des chaînes d'épissage +=. cette méthode d'épissage est très faible. Nous pouvons utiliser une méthode intelligente pour épisser des chaînes, qui consiste à utiliser la méthode de jointure du tableau.
<p class="one" id="one"></p> <input type="button" value="效率低" onclick="func1()" /> <input type="button" value="效率高" onclick="func2()" /> //效率低的 function func1(){ var start = new Date().getTime(); var template = ""; for(var i = 0; i < 10000; i++){ template += "<input type='button' value='a'>"; } var end = new Date().getTime(); document.getElementById("one").innerHTML = template; alert("用时:" + (end - start) + "毫秒"); } //效率高的 function func2(){ var start = new Date().getTime(); var array = []; for(var i = 0; i < 10000; i++){ array[i] = "<input type='button' value='a'>"; } var end = new Date().getTime(); document.getElementById("one").innerHTML = array.join(""); alert("用时:" + (end - start) + "毫秒"); }
Regardons son exécution sous différents navigateurs
Nous constaterons que la différence sous IE6 est assez évidente. La situation est également très évidente dans les versions supérieures d'IE, mais il n'y a pas beaucoup de différence sous Firefox. Au contraire, l'efficacité relative du deuxième type est encore plus faible, mais la différence n'est que d'environ 2 ms, et Chrome est similaire à Firefox. . De plus, d'ailleurs, lorsque nous ajoutons des éléments au tableau, beaucoup de gens aiment utiliser la méthode native de push du tableau. En fait, il est plus rapide d'utiliser directement arr[i] ou arr[arr.length], soit environ 10 000. Dans le cas de boucles multiples, il y aura une différence de plus de dix millisecondes sous le navigateur IE.
2. boucle for
La boucle for est une situation que l'on rencontre souvent. Regardons l'exemple suivant :
<input type="button" value="效率低" onclick="func1()" /> <input type="button" value="效率高" onclick="func2()" /> var arr = []; for(var i = 0; i < 10000; i++){ arr[i] = "<p>" + i + "</p>"; } document.body.innerHTML += arr.join(""); //效率低的 function func1(){ var ps = document.getElementsByTagName("p"); var start = new Date().getTime(); for(var i = 0; i < ps.length; i++){ //"效率低" } var end = new Date().getTime(); alert("用时:" + (end - start) + "毫秒"); } //效率高的 function func2(){ var ps = document.getElementsByTagName("p"); var start = new Date().getTime(); for(var i = 0, len = ps.length; i < len; i++){ //"效率高" } var end = new Date().getTime(); alert("用时:" + (end - start) + "毫秒"); }
Comme le montre le tableau ci-dessus, la différence est très évidente sous IE6.0, alors qu'il n'y a presque aucune différence sous Firefox et Chrome. La raison pour laquelle cela se produit sous IE6.0 est principalement parce que la boucle for est présente. Pendant l'exécution, le premier cas calculera la longueur à chaque fois, tandis que le second cas calculera la longueur au début et la sauvegardera dans une variable, donc son efficacité d'exécution est plus élevée, donc lorsque nous utilisons Lorsque nous faisons une boucle for, surtout si nous devons calculer la longueur, nous devrions commencer à la sauvegarder dans une variable. Mais il n'y a pas de différence aussi évidente tant que la longueur est obtenue. Si nous exploitons uniquement un tableau et obtenons la longueur d'un tableau, alors les deux méthodes d'écriture sont en fait similaires. Regardons l'exemple suivant :
.<input type="button" value="效率低" onclick="func1()" /> <input type="button" value="效率高" onclick="func2()" /> var arr2 = []; for(var i = 0; i < 10000; i++){ arr2[i] = "<p>" + i + "</p>"; } //效率低的 function func1(){ var start = new Date().getTime(); for(var i = 0; i < arr2.length; i++){ //"效率低" } var end = new Date().getTime(); alert("用时:" + (end - start) + "毫秒"); } //效率高的 function func2(){ var start = new Date().getTime(); for(var i = 0, len = arr2.length; i < len; i++){ //"效率高" } var end = new Date().getTime(); alert("用时:" + (end - start) + "毫秒"); }
Comme le montre le tableau ci-dessus, s'il ne s'agit que d'un tableau, nous pouvons voir que les deux méthodes d'écriture sont presque les mêmes. En fait, si nous augmentons. la boucle à 100 000 fois. En d'autres termes, la différence n'est que de quelques millisecondes, donc dans le cas des tableaux, je pense que ce sont les mêmes. Concernant l'optimisation de la boucle for, certaines personnes ont également avancé de nombreux points. Certaines personnes pensent qu'utiliser -=1, ou boucler de grand à petit, etc., je pense que ces optimisations ne se reflètent souvent pas. situations réelles. En un mot, ce n'est qu'un petit changement au niveau informatique, mais ce que cela nous apporte, c'est que la lisibilité du code est fortement réduite, donc cela n'en vaut vraiment pas la peine.
3. Réduire le redessinage des pages
Réduire le redessinage des pages n'est pas essentiellement une optimisation de JS lui-même, mais cela est souvent causé par JS, et le redessinage affecte souvent sérieusement les performances de la page, c'est donc le cas. complètement nécessaire de l'enlever. Regardons l'exemple suivant :
<p id="demo"></p> <input type="button" value="效率低" onclick="func1()" /> <input type="button" value="效率高" onclick="func2()" /> var str = "<p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p>"; //效率低的 function func1(){ var obj = document.getElementById("demo"); var start = new Date().getTime(); for(var i = 0; i < 100; i++){ obj.innerHTML += str + i; } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒"); } //效率高的 function func2(){ var obj = document.getElementById("demo"); var start = new Date().getTime(); var arr = []; for(var i = 0; i < 100; i++){ arr[i] = str + i; } obj.innerHTML = arr.join(""); var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒");
Ce que vous pouvez voir, c'est que c'est un résultat étonnant, juste 100 fois le cycle, non. quel que soit le navigateur sous lequel il se trouve, il y a une si grande différence. De plus, nous avons également constaté qu'ici, l'efficacité d'exécution d'IE6 est en fait bien meilleure que celle de Firefox. On peut voir que Firefox n'a aucune performance en matière de redessinage de page. Faites une optimisation. Il convient également de noter ici que ce n'est pas seulement innerHTML qui affecte généralement le redessinage des pages. La modification du style, de la position, etc. des éléments déclenchera le redessinage des pages, vous devez donc y prêter attention en temps normal.
4. Réduisez le nombre de recherches sur la chaîne de portée
Nous savons que lorsque le code js est exécuté, s'il doit accéder à une variable ou à une fonction, il doit parcourir la chaîne de portée du courant. environnement d'exécution, et le parcours consiste à parcourir en arrière niveau par niveau depuis l'extrémité avant de cette chaîne de portée jusqu'à l'environnement d'exécution global, il y a donc souvent une situation ici, c'est-à-dire si nous devons accéder fréquemment aux objets variables de l'environnement global , nous le ferons A chaque fois, la chaîne de scope actuelle doit être parcourue niveau par niveau, ce qui prend évidemment du temps. Regardons l'exemple suivant :
<p id="demo"></p> <input id="but1" type="button" onclick="func1()" value="效率低"/> <input id="but2" type="button" onclick="func2()" value="效率高"/> function func1(){ var start = new Date().getTime(); for(var i = 0; i < 10000; i++){ var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); var but1 = document.getElementById("but1"); var but2 = document.getElementById("but2"); var inputs = document.getElementsByTagName("input"); var ps = document.getElementsByTagName("p"); } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒"); } function func2(){ var start = new Date().getTime(); var doc = document; for(var i = 0; i < 10000; i++){ var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); var but1 = doc.getElementById("but1"); var but2 = doc.getElementById("but2"); var inputs = doc.getElementsByTagName("input"); var ps = doc.getElementsByTagName("p"); } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒");
上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了,所以我们看看其执行结果:
从上表中可以看出,其在IE6下差别还是非常明显的,而且这种差别在多级作用域链和多个全局变量的情况下还会表现的非常明显。
5、避免双重解释
双重解释的情况也是我们经常会碰到的,有的时候我们没怎么考虑到这种情况会影响到效率,双重解释一般在我们使用eval、new Function和setTimeout等情况下会遇到,我们看看下面的例子:
<p id="demo"></p> <input id="but1" type="button" onclick="func1()" value="效率低"/> <input id="but2" type="button" onclick="func2()" value="效率高"/> var sum, num1 = 1, num2 = 2; function func1(){ var start = new Date().getTime(); for(var i = 0; i < 10000; i++){ var func = new Function("sum+=num1;num1+=num2;num2++;"); func(); } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒"); } function func2(){ var start = new Date().getTime(); for(var i = 0; i < 10000; i++){ sum+=num1; num1+=num2; num2++; } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒"); }
第一种情况我们是使用了new Function来进行双重解释,而第二种是避免了双重解释,我们看看在不同浏览器下的表现:
可以看到,在所有的浏览器中,双重解释都是有很大开销的,所以在实际当中要尽量避免双重解释。
感谢”SeaSunK”对第四点测试报告错误的指正,现在已经修改过来了。至于最后一点提出的func1每次都初始化,没有可比性,所以我给换了eval,结果发现,在IE6.0下还是有影响,而且在Firefox下,使用eval对效率的影响程度更加厉害,在Firefox下,如果10000次循环,需要十多秒的时间,所以我把循环都变成了1000次。看代码和报告。
var sum, num1 = 1, num2 = 2; function func1(){ var start = new Date().getTime(); for(var i = 0; i < 1000; i++){ eval("sum+=num1;num1+=num2;num2++;"); } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒"); } function func2(){ var start = new Date().getTime(); for(var i = 0; i < 1000; i++){ sum+=num1; num1+=num2; num2++; } var end = new Date().getTime(); alert("用时 " + (end - start) + " 毫秒");
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
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!