Heim  >  Artikel  >  Web-Frontend  >  JavaScript-optimiertes DOM

JavaScript-optimiertes DOM

php中世界最好的语言
php中世界最好的语言Original
2018-03-19 16:27:091825Durchsuche

Dieses Mal werde ich Ihnen die JavaScript-Optimierung von DOM vorstellen und welche Vorsichtsmaßnahmen für die Optimierung von DOM in JavaScript gelten. Hier sind praktische Fälle, werfen wir einen Blick darauf.

Die Optimierung von DOM beginnt mit dem Neuzeichnen und Neuanordnen, vor langer, langer Zeit...

Neuzeichnen und Neuanordnen

1.1 Was sind Neuzeichnen und Neuanordnen? Neuanordnung bedeutet, dass sich die Position oder Größe eines Elements geändert hat und der Browser den Rendering-Baum neu berechnen muss. Nachdem der neue Rendering-Baum erstellt wurde, zeichnet der Browser die betroffenen Elemente neu.

1.2 Browser-Rendering-Seite

Wenn Sie zu einem Vorstellungsgespräch gehen, wird Ihnen immer eine Frage gestellt, nämlich „Geben Sie eine Zeile ein.“ der URL in den Browser. „Was ist passiert?“ betrifft die Antwort auf diese Frage nicht nur Netzwerkkenntnisse, sondern auch die Frage der Browserdarstellung der Seite. Wenn unser Browser die Antwort vom Server empfängt, beginnt er mit dem Rendern. Wenn er auf CSS trifft, berechnet er asynchron den DOM-Baum gebildet, der asynchron

Der berechnete Stil (Style-Box) wird mit dem DOM-Baum kombiniert, um einen Render-Baum zu bilden, der dann vom Browser auf der Seite gezeichnet wird.

Der Unterschied zwischen dem DOM-Baum und dem Render-Baum besteht darin, dass Knoten mit dem Stil display:none; im DOM-Baum, aber nicht im Render-Baum vorhanden sind.

Nach dem Zeichnen beginnt der Browser mit dem Parsen der JS-Datei und bestimmt basierend auf dem JS, ob ein Neuzeichnen und ein Reflow durchgeführt werden soll.

1.3 Gründe für Neuzeichnen und NeufließenFaktoren, die Neuzeichnen verursachen:

Das Ändern der

Sichtbarkeit, der Umrisslinie, der Hintergrundfarbe und anderer Stilattribute hat keine Auswirkungen auf die Elementgröße, Position usw. Der Browser wird basierend auf den neuen Eigenschaften des Elements neu gezeichnet.

  • Faktoren, die eine Neuordnung verursachen:

  • Inhaltsänderung

Textänderungen oder Bildgrößenänderungen
  • Änderungen in den geometrischen Eigenschaften von DOM-Elementen
    • Zum Beispiel Wenn die Breiten- und Höhenwerte eines DOM-Elements geändert werden, werden die relevanten Knoten im ursprünglichen Rendering-Baum ungültig und der Browser ordnet die relevanten Knoten im Rendering-Baum basierend auf dem geänderten DOM neu an. Wenn sich die geometrischen Attribute des übergeordneten Knotens ändern, werden die Positionen seiner untergeordneten Knoten und nachfolgenden Geschwisterknoten neu berechnet, was zu einer Reihe von Neuanordnungen führt.
  • Strukturänderungen des DOM-Baums
    DOM-Knoten
  • hinzufügen, DOM-Knotenposition ändern und Das Löschen eines Knotens stellt eine Änderung des DOM-Baums dar, die zu einer Neuanordnung der Seite führt. Das Browser-Layout ist ein Prozess von oben nach unten. Das Ändern des aktuellen Elements hat keine Auswirkungen auf die zuvor durchlaufenen Elemente. Wenn jedoch ein neues Element vor allen Knoten hinzugefügt wird, werden alle nachfolgenden Elemente neu angeordnet.

    • Einige Attribute abrufen

    • Zusätzlich zu direkten Änderungen im Rendering-Baum werden beim Abrufen einiger Attributwerte die Es wird auch eine Neuanordnung des Browsers durchgeführt, um den korrekten Wert zu erhalten:
    ,
  • ,

    ,

    ,
  • ,
      ,
    • ,

      , offsetTop, offsetLeft, offsetWidth, offsetHeight. scrollTop

  • Änderungen in der Browserfenstergröße

    • Änderungen in der Fenstergröße wirken sich auf Änderungen in der Größe von Elementen innerhalb der gesamten Webseite aus. Das heißt, DOM-Elemente Die Sammlungseigenschaften ändern sich, was zu einer Neuanordnung führt.

  • Das Erscheinen der Bildlaufleiste (löst den Reflow der gesamten Seite aus)

Kurz gesagt, Sie müssen es wissen dass js Single-Threaded ist, blockiert das Neuzeichnen und Neufließen die Leistung der Webseite, wenn eine Seite mehrmals neu gezeichnet und neu gegliedert wird, z. Die Seite bleibt möglicherweise immer mehr hängen, daher müssen wir das Neuzeichnen und Umfließen so weit wie möglich reduzieren. Dann basiert auch unsere Optimierung von DOM auf diesem Ausgangspunkt.

2. Optimierung

2.1 Zugriff reduzieren

Die Anzahl der Zugriffe zu reduzieren bedeutet natürlich, Elemente zwischenzuspeichern, aber achten Sie darauf >

Dadurch wird ele nicht zwischengespeichert. Jedes Mal, wenn Sie ele aufrufen, entspricht dies dem Besuch des Knotens mit der ID von ele.
var ele = document.getElementById('ele');

2.1.1 Cache NodeList

Wir können Lebensmittel[i] verwenden, um mit der Klasse Lebensmittel auf das i-te Element zuzugreifen, die Lebensmittel hier jedoch nicht Ein Array, aber eine NodeList. NodeList ist ein Array-ähnliches Array, das einige geordnete Knoten speichert und auf diese Knoten nach Position zugreifen kann. NodeList-Objekte sind dynamisch und bei jedem Zugriff wird eine dokumentbasierte Abfrage ausgeführt. Daher müssen wir die Anzahl der Besuche bei NodeList minimieren und können erwägen, den Wert von NodeList zwischenzuspeichern.
var foods = document.getElementsByClassName('food');

Und da sich NodeList dynamisch ändert, kann es, wenn es nicht zwischengespeichert wird, zu einer Endlosschleife führen, z. B. beim Hinzufügen von Elementen, während die Länge von NodeList ermittelt wird.
// 优化前var lis = document.getElementsByTagName('li');for(var i = 0; i < lis.length; i++) {     // do something...  }// 优化后,将length的值缓存起来就不会每次都去查询length的值var lis = document.getElementsByTagName('li');for(var i = 0, len = lis.length; i < len; i++) {     // do something...  }

2.1.2 Ändern des Selektors

Es gibt zwei gängige Methoden zum Abrufen von Elementen: getElementsByXXX() und queryselectorAll(). Der erste ist sehr groß Holen Sie sich eine dynamische Sammlung. Letzteres dient beispielsweise dazu, eine statische Sammlung zu erhalten.

Vorgänge für statische Sammlungen führen nicht zu einer erneuten Abfrage von Dokumenten, was optimierter ist als dynamische Sammlungen.
// 假设一开始有2个livar lis = document.getElementsByTagName('li');  // 动态集合var ul = document.getElementsByTagName('ul')[0]; 
for(var i = 0; i < 3; i++) {
    console.log(lis.length);    var newLi = document.createElement('li'); 
    ul.appendChild(newLi);
}// 输出结果:2, 3, 4var lis = document.querySelector('li');  // 静态集合 var ul = document.getElementsByTagName('ul')[0]; 
for(var i = 0; i < 3; i++) {
    console.log(lis.length);    var newLi = document.createElement('li'); 
    ul.appendChild(newLi);
}// 输出结果:2, 2, 2

2.1.3 Vermeiden Sie unnötige Schleifen

// 优化前
for(var i = 0; i < 10; i++) {
    document.getElementById('ele').innerHTML += 'a';
Der voroptimierte Code greift zehnmal auf das Element ele zu, während der optimierte Code nur einmal darauf zugreift, was eine enorme Verbesserung darstellt Effizienz.
} 
// 优化后 
var str = ''; 
for(var i = 0; i < 10; i++) {
    str += 'a'; 
}
document.getElementById('ele').innerHTML = str;

2.1.4 Ereignisdelegierter

Die Ereignisfunktionen in js sind alle Objekte. Wenn zu viele Ereignisfunktionen vorhanden sind, wird viel Speicher belegt und desto mehr DOM-Elemente werden gebunden Je länger der Zugriff auf die Dom-Zeiten dauert, desto länger dauert es auch, bis die Seite interaktiv bereit ist. Aus diesem Grund wurde die Ereignisdelegation geboren, die das Event-Bubbling verwendet, um alle Ereignisse eines bestimmten Typs zu verwalten, indem nur ein

Event-Handler-Programm

angegeben wird.

Wir haben lis.length mal li vor der Event-Delegation besucht, aber wir haben ul nur einmal besucht, nachdem wir die Event-Delegation verwendet haben.
// 事件委托前var lis = document.getElementsByTagName('li');for(var i = 0; i < lis.length; i++) {
   lis[i].onclick = function() {
      console.log(this.innerHTML);
   };  
}    
// 事件委托后var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(event) {
   console.log(event.target.innerHTML);
};

2.2 Neuzeichnen und Neuanordnen reduzieren

2.2.1 Mehrere Stile eines Dom-Knotens ändern

Wir wollen Um die Breite und Höhe eines p-Elements zu ändern, kann man wie folgt vorgehen: neu zeichnen. Wir haben gesagt, dass die Optimierung darin besteht, die Anzahl der Besuche und die Anzahl der Neuzeichnungen und Nachbestellungen zu reduzieren. Können wir von diesem Ausgangspunkt aus nur einmal auf das Element zugreifen und die Anzahl der Nachbestellungen auf 1 reduzieren? Offensichtlich ist es möglich, dass wir eine Klasse in CSS schreiben können

Auf diese Weise können wir mehrere Stile gleichzeitig bedienen

 p = document.getElementById('p1'
2.2.2 Dom-Knotenstile stapelweise ändern

Der obige Code gilt für einen DOM-Knoten. Was ist, wenn wir den Stil einer DOM-Sammlung ändern möchten?
/* css
.change {
    width: 220px;
    height: 300px;
}*/document.getElementById('p').className = 'change';

Die erste Methode, die mir in den Sinn kommt, besteht darin, die Sammlung zu durchlaufen und jedem Knoten einen Klassennamen hinzuzufügen. Denken Sie noch einmal darüber nach: Bedeutet das nicht, dass Sie den DOM-Knoten mehrmals besucht haben? Denken Sie an den Unterschied zwischen dem DOM-Baum und dem am Anfang des Artikels erwähnten Rendering-Baum. Wenn das Anzeigeattribut eines Knotens „none“ ist, ist dieser Knoten nicht im Rendering-Baum vorhanden, was bedeutet, dass die Operation dieses Knotens nicht möglich ist wirkt sich nicht auf den Renderbaum aus und verursacht kein Neuzeichnen und Neuanordnen. Basierend auf dieser Idee können wir eine Optimierung erreichen:

Zeigt das übergeordnete Element der zu ändernden Sammlung an: keines;

  • 之后遍历修改集合节点

  • 将集合父元素display: block;

  • // 假设增加的class为.changevar lis = document.getElementsByTagName('li');  
    var ul = document.getElementsByTagName('ul')[0];
    ul.style.display = 'none';for(var i = 0; i < lis.length; i++) {
        lis[i].className = 'change';  
    }
    ul.style.display = 'block';

    3、总结

    • 减少访问dom的次数

      • 缓存节点属性值

      • 选择器的使用

      • 避免不必要的循环

      • 事件委托

    • 减少重绘与重排

      • 使用className改变多个样式

      • 使父元素脱离文档流再恢复

    相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

    推荐阅读:

    Vue的计算属性

    Webpack模块的使用

    Das obige ist der detaillierte Inhalt vonJavaScript-optimiertes DOM. 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