Javascript-Leistungsoptimierung ist keineswegs eine schriftliche Technik. Nicholas‘ technische Entwicklung listet 10 Vorschläge auf, die Ihnen helfen sollen, effizienten JS-Code zu schreiben
Definieren Sie lokale Variablen
Wenn auf eine Variable verwiesen wird, sucht JavaScript in verschiedenen Mitgliedern der Bereichskette nach der Variablen. Die Bereichskette bezieht sich auf den Satz verfügbarer Variablen, die derzeit auf sie wirken. Sie besteht in verschiedenen Mainstream-Browsern aus mindestens zwei Teilen: dem Satz lokaler Variablen und dem Satz globaler Variablen.
Einfach ausgedrückt: Je tiefer die JavaScript-Engine in der Bereichskette sucht, desto länger dauert der Vorgang. Die Engine sucht ausgehend davon zunächst nach lokalen Variablen, dann nach Funktionsparametern, lokal definierten Variablen und iteriert schließlich durch alle globalen Variablen.
Da lokale Variablen am Anfang der Kette stehen, ist es immer einfacher, lokale Variablen zu finden als globale Variablen. Wenn Sie also eine globale Variable mehr als einmal verwenden möchten, sollten Sie sie wie folgt als lokale Variable definieren:
var blah = document.getElementById('myID'), blah2 = document.getElementById('myID2');
umgeschrieben als
var doc = document, blah = doc.getElementById('myID'), blah2 = doc.getElementById('myID2');
2. Verwenden Sie nicht die with()-Anweisung
Dies liegt daran, dass sich die with()-Anweisung in der Gültigkeitskette Start befindet Hinzufügen zusätzlicher Variablen. Die zusätzlichen Variablen bedeuten, dass die JavaScript-Engine beim Zugriff auf eine Variable zuerst die von der with()-Anweisung generierten Variablen scannen muss, dann die lokalen Variablen und schließlich die globalen Variablen.
Mit() ergeben sich also im Wesentlichen alle Leistungsnachteile globaler Variablen für lokale Variablen, was wiederum dazu führt, dass die Javascript-Optimierung scheitert.
3. Gehen Sie mit Verschlüssen vorsichtig um
Obwohl Sie vielleicht noch nichts über „Verschlüsse“ wissen, verwenden Sie diese Technik möglicherweise oft, ohne es zu merken. Abschlüsse gelten in JavaScript grundsätzlich als neu, wenn wir eine unmittelbare Funktion definieren, wie zum Beispiel:
document.getElementById('foo').onclick = function(ev) { };
Das Problem mit Abschlüssen besteht darin, dass in ihnen per Definition mindestens drei Objekte im Gültigkeitsbereich vorhanden sind Kette: Abschlussvariablen, lokale Variablen und globale Variablen. Diese zusätzlichen Objekte verursachen die in den Vorschlägen 1 und 2 genannten Leistungsprobleme.
Aber ich denke, Nicholas fordert uns nicht auf, mit dem Essen aufzuhören, weil wir ersticken. Schließungen sind immer noch sehr nützlich, um die Lesbarkeit von Code usw. zu verbessern. Missbrauchen Sie sie nur nicht (insbesondere in Schleifen).
4. Objektattribute und Array-Elemente sind langsamer als Variablen
Wenn es um JavaScript-Daten geht, gibt es im Allgemeinen 4 Zugriffsmethoden: numerische Werte, Variablen, Objekteigenschaften und Array-Elemente. Wenn man Optimierungen in Betracht zieht, erbringen Zahlen und Variablen ungefähr die gleiche Leistung und sind deutlich schneller als Objekteigenschaften und Array-Elemente.
Wenn Sie also mehrmals auf eine Objekteigenschaft oder ein Array-Element verweisen, können Sie durch die Definition einer Variablen Leistungsverbesserungen erzielen. (Diese Regel gilt beim Lesen und Schreiben von Daten)
Obwohl diese Regel in den meisten Fällen korrekt ist, hat Firefox einige interessante Arbeiten bei der Optimierung von Array-Indizes durchgeführt, wodurch die tatsächliche Leistung besser als die von Variablen werden kann. Angesichts der Leistungsnachteile von Array-Elementen in anderen Browsern sollten Sie jedoch versuchen, Array-Suchen zu vermeiden, es sei denn, Sie entwickeln wirklich nur für die Leistung von Firefox.
Graben Sie nicht zu tief in das Array
Außerdem sollten Programmierer es vermeiden, zu tief in das Array einzudringen, denn je mehr Ebenen Sie betreten, desto schlechter wird der Vorgang Geschwindigkeit ist langsamer.
Einfach ausgedrückt sind Operationen in Arrays mit vielen Verschachtelungsebenen langsam, weil die Suche nach Array-Elementen langsam ist. Stellen Sie sich vor, dass Sie, wenn Sie mit Array-Elementen arbeiten, die auf drei Ebenen verschachtelt sind, drei Array-Elementsuchen statt einer durchführen müssen.
Wenn Sie also weiterhin auf foo.bar verweisen, können Sie die Leistung verbessern, indem Sie var bar = foo.bar definieren.
6. Vermeiden Sie For-In-Schleifen (und funktionsbasierte Iteration)
Hier ist ein weiterer sehr dogmatischer Ratschlag: Verwenden Sie keine For-In-Schleifen.
Die Logik dahinter ist sehr einfach: Um die Elemente in einer Sammlung zu durchlaufen, können Sie eine for-Schleife oder eine do-while-Schleife anstelle einer for-in-Schleife verwenden Um zusätzliche Array-Elemente zu durchlaufen, ist mehr Zeit erforderlich.
Um diese Elemente zu iterieren, muss JavaScript für jedes Element eine Funktion erstellen. Diese funktionsbasierte Iteration bringt eine Reihe von Leistungsproblemen mit sich: Die zusätzlichen Funktionen führen den Kontext ein, in dem das Funktionsobjekt erstellt und zerstört wird wird in Kraft treten. Zusätzliche Elemente werden am Anfang der Domänenkette hinzugefügt.
7. Kontrollbedingungen und Kontrollvariablen beim Schleifen kombinieren
Wenn es um die Leistung geht, war die Arbeit, die in Schleifen vermieden werden muss, schon immer ein heißes Thema. weil Schleifen viele Male wiederholt ausgeführt werden. Wenn also eine Leistungsoptimierung erforderlich ist, kann die offensichtlichste Leistungsverbesserung dadurch erzielt werden, dass zuerst die Schleife bearbeitet wird.
Eine Möglichkeit, eine Schleife zu optimieren, besteht darin, die Steuerbedingungen und Steuervariablen bei der Definition der Schleife zu kombinieren. Hier ist ein Beispiel, ohne sie zusammenzuführen:
for ( var x = 0; x < 10; x++ ) { };
Wann Wenn wir dieser Schleife etwas hinzufügen, stellen wir fest, dass in jeder Iteration mehrere Operationen auftreten. Die JavaScript-Engine erfordert:
#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('p'); for (var i=0; i < ps.length; i++ ) { var p = document.createElement("p"); document.appendChild(p); }
这段代码造成了死循环,因为 ps 表示一个实时的HTML集合,并不是你所期望的数组。这种实时的集合在添加
标签时被更新,所以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('p') ); 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上添加样式结点也是不错的选择。
Das obige ist der detaillierte Inhalt vonZusammenfassung der Tipps zur Verbesserung der JavaScript-Webleistung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!