Heim  >  Artikel  >  Web-Frontend  >  Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

亚连
亚连Original
2018-05-18 15:39:541443Durchsuche

Die Ausführungseffizienz von JS-Code wirkt sich oft direkt auf die Leistung der Seite aus. Manchmal ist die Effizienz verschiedener JS-Codes sehr unterschiedlich. Natürlich liegt es an unseren Schreibgewohnheiten , die meisten davon haben uns bei der Optimierung geholfen, aber in China gibt es den bösen IE6 immer noch in großer Zahl, und wir müssen darüber nachdenken. In Bezug auf die Optimierung von JS-Code gibt es tatsächlich viele Situationen, von denen einige relativ geringe Auswirkungen haben und andere schwerwiegender sind. In diesem Artikel liste ich einige Situationen auf, die meiner Meinung nach schwerwiegende Auswirkungen haben.

1. String-Spleißen

String-Spleißen kommt in unserer Entwicklung häufig vor, daher sind wir es oft gewohnt, Strings direkt zu spleißen Diese Spleißmethode ist sehr niedrig. Wir können eine clevere Methode zum Spleißen von Zeichenfolgen verwenden, nämlich die Join-Methode des Arrays.

<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=&#39;button&#39; value=&#39;a&#39;>";   
    }   
    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=&#39;button&#39; value=&#39;a&#39;>";   
    }   
    var end = new Date().getTime();   
    document.getElementById("one").innerHTML = array.join("");   
    alert("用时:" + (end - start) + "毫秒");   }

Werfen wir einen Blick auf die Ausführung unter verschiedenen Browsern

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

Wir werden feststellen, dass der Unterschied unter IE6 ziemlich offensichtlich ist. Tatsächlich ist dies diese Situation Dies ist auch in höheren Versionen des IE sehr offensichtlich, aber unter Firefox gibt es keinen großen Unterschied. Im Gegenteil, die relative Effizienz des zweiten Typs ist noch geringer, aber der Unterschied beträgt nur etwa 2 ms, und Chrome ähnelt Firefox. Wenn wir dem Array Elemente hinzufügen, verwenden viele Leute übrigens gerne die native Methode von push. Tatsächlich ist es schneller, arr[i] oder arr[arr.length] direkt zu verwenden 10000. Bei mehreren Schleifen ergibt sich unter dem IE-Browser ein Unterschied von mehr als zehn Millisekunden.

2. for-Schleife

Die for-Schleife ist eine Situation, der wir häufig begegnen:

<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) + "毫秒");   
}

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

Wie aus der obigen Tabelle hervorgeht, ist der Unterschied unter IE6.0 sehr offensichtlich, während es unter Firefox und Chrome fast keinen Unterschied gibt. Der Grund, warum dies unter IE6.0 passiert, liegt hauptsächlich darin, dass die for-Schleife ausgeführt wird Im ersten Fall wird die Länge jedes Mal berechnet, im zweiten Fall wird die Länge jedoch zu Beginn berechnet und in einer Variablen gespeichert, sodass die Ausführungseffizienz höher ist. Wenn wir also eine for-Schleife verwenden, insbesondere wenn wir die Länge berechnen müssen , sollten wir damit beginnen, es in einer Variablen zu speichern. Aber es gibt keinen so offensichtlichen Unterschied, solange wir nur ein Array bearbeiten und die Länge eines Arrays erhalten, dann sind die beiden Schreibweisen tatsächlich ähnlich:

<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) + "毫秒");   
}

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

Wie aus der obigen Tabelle ersichtlich ist, können wir sehen, dass die beiden Schreibmethoden fast gleich sind, wenn wir die Schleife vergrößern bis 100.000 Mal. Der Unterschied beträgt nur wenige Millisekunden, daher denke ich, dass sie im Fall von Arrays gleich sind. In Bezug auf die Optimierung der for-Schleife haben einige Leute auch viele Punkte vorgebracht. Einige Leute denken, dass die Verwendung von -=1 oder das Schleifen von groß nach klein usw. meiner Meinung nach völlig unnötig ist alles in tatsächlichen Situationen. Kurz gesagt, es handelt sich nur um eine kleine Änderung auf Computerebene, aber sie führt dazu, dass die Lesbarkeit des Codes stark eingeschränkt wird, sodass sich der Gewinn wirklich nicht lohnt.

3. Reduzieren Sie das Neuzeichnen von Seiten

Das Reduzieren des Neuzeichnens von Seiten ist nicht unbedingt eine Optimierung von JS selbst, wird aber oft durch JS verursacht, und das Neuzeichnen beeinträchtigt oft die Leistung der Seite Es ist absolut notwendig, es herauszunehmen. Schauen wir uns das folgende Beispiel an:

<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) + " 毫秒");

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

Was Sie sehen können, ist, dass dies ein erstaunliches Ergebnis ist, nur 100 Mal wiederholt, egal Unter welchem ​​Browser es sich befindet, gibt es einen so großen Unterschied. Außerdem haben wir festgestellt, dass die Ausführungseffizienz von IE6 tatsächlich viel besser ist als die von Firefox. Es ist ersichtlich, dass Firefox in Bezug auf die Seite nichts getan hat Neuzeichnung. Es sollte hier auch beachtet werden, dass es nicht nur innerHTML ist, das sich im Allgemeinen auf das Neuzeichnen der Seite auswirkt. Das Ändern des Stils, der Position usw. von Elementen löst ein Neuzeichnen der Seite aus, daher müssen Sie in normalen Zeiten darauf achten.

4. Reduzieren Sie die Anzahl der Suchvorgänge in der Bereichskette
Wir wissen, dass js-Code, wenn er auf eine Variable oder Funktion zugreifen muss, die aktuelle Bereichskette durchlaufen muss Ausführungsumgebung, und Durchquerung besteht darin, Ebene für Ebene vom vorderen Ende dieser Bereichskette bis zur globalen Ausführungsumgebung rückwärts zu durchlaufen. Daher gibt es hier häufig eine Situation, wenn wir häufig auf die variablen Objekte der globalen Umgebung zugreifen müssen , wir müssen jedes Mal die aktuelle Bereichskette Ebene für Ebene durchlaufen, was offensichtlich zeitaufwändig ist: Schauen wir uns das folgende Beispiel an:

<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) + " 毫秒");

上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了,所以我们看看其执行结果: 

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

从上表中可以看出,其在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来进行双重解释,而第二种是避免了双重解释,我们看看在不同浏览器下的表现: 

 Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

可以看到,在所有的浏览器中,双重解释都是有很大开销的,所以在实际当中要尽量避免双重解释。

感谢”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) + " 毫秒");

Informationen zur Optimierung Ihres JS-Codes (grafisches Tutorial)

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JavaScript设计模式系列一:工厂模式

JavaScript设计模式系列二:单例模式

JavaScript设计模式系列三:建造者模式

Das obige ist der detaillierte Inhalt vonInformationen zur Optimierung Ihres JS-Codes (grafisches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn