Maison >interface Web >js tutoriel >Comment optimiser les nœuds Dom

Comment optimiser les nœuds Dom

醉折花枝作酒筹
醉折花枝作酒筹original
2021-04-12 11:16:392485parcourir

Cet article vous présentera le plan d'optimisation du nœud Dom. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Comment optimiser les nœuds Dom

L'opération DOM a le plus grand impact sur les performances car elle conduit au redessinage et à la redistribution du navigateur. Nous savons tous que les modifications dans l'interface utilisateur de la page sont obtenues via les opérations DOM. Des API sont fournies pour nous faciliter l'exploitation du DOM, le coût des opérations DOM est très élevé et la plupart des goulots d'étranglement des performances du code frontal de la page sont concentrés sur les opérations DOM. Par conséquent, l'optimisation des performances frontales est un objectif majeur. est l'optimisation des opérations DOM.

Mécanisme de rendu du navigateur :

Comment optimiser les nœuds Dom
Le navigateur rend la page
Comment optimiser les nœuds Dom

  1. Le navigateur analyse le code source du document HTML, puis construisez un arbre DOM et calculez-le de manière asynchrone lorsque vous rencontrez des styles.

  2. Le style calculé de manière asynchrone est combiné avec l'arborescence DOM pour construire l'arborescence de rendu.

  3. Disposez l'arbre de rendu.

  4. Peignez l'arbre de rendu.

La différence entre l'arborescence DOM et l'arborescence de rendu est que les nœuds avec le style display:none; seront dans l'arborescence DOM mais pas dans l'arborescence de rendu. Une fois que le navigateur l'a dessiné, il commence à analyser le fichier js et à déterminer s'il doit être redessiné et redistribué en fonction du fichier js.

Reflow·Redraw

Opérations qui se produisent lorsque la page change :

  1. Reflow : le moteur du navigateur détecte qu'un certain nœud dans l'arbre de rendu a changé, affectant la mise en page, qui nécessite un retour en arrière et un nouveau rendu. Nous appelons ce processus de restauration reflow. Reflow reviendra vers le bas à partir de ce cadre racine, calculant les dimensions géométriques et les positions de tous les nœuds en séquence.
  2. Redessiner : modifiez la couleur d'arrière-plan, la couleur du texte, la couleur de la bordure, etc. d'un élément sans affecter la disposition DOM de la page.

js est monothread, le redessin et la redistribution bloqueront les opérations de l'utilisateur et affecteront les performances de la page Web

Optimisation : réduisez le nombre de redessins de redistribution

1, modifiez plusieurs styles dom, utilisez la classe au lieu du style pour réduire les multiples déclencheurs de refusion et redessiner
Exemple : modifier la largeur et la hauteur de l'élément dom

var dom = document.getElementById('box')
dom.style.width = '300px'
dom.style.height = '300px'//访问了三次dom,触发了两次回流和两次重绘

Après optimisation :

.change {
    width: 300px;
    height: 300px;
    }
    document.getElementById('p').className = 'change'//只触发一次

2. Modifiez par lots le type de liste, rompez avec le flux de documents puis restaurez-le. Les nœuds avec le style display:none; seront dans l'arborescence DOM mais pas dans l'arborescence de rendu et ne provoqueront pas de refonte.

Si vous souhaitez ajouter une classe à chaque nœud enfant DOM dans une collection DOM, nous pouvons parcourir et ajouter la classe à chaque nœud, déclenchant ainsi plusieurs redessins et redistributions

/* //需要加入的样式
.change {
    width: 300px;
    height: 300px;
}
*/
var ul = document.getElementsByTagName('ul')
var lis = document.getElementsByTagName('li') 
ul.style.display = 'none'
for(var i = 0; i < lis.length; i++) {
    lis[i].className = &#39;change&#39;;
     }
     ul.style.display = &#39;block&#39;

3. DocumentFragment

Le DOM virtuel est en fait un objet. js fournit la méthode reateDocumentFragment() pour créer un objet nœud virtuel vide. Le nœud DocumentFragment n'appartient pas à l'arborescence du document lorsque plusieurs éléments DOM sont nécessaires. à ajouter, si ces éléments sont d'abord ajoutés au DocumentFragment, puis que l'objet DocumentFragment est ajouté à l'arborescence de rendu, le nombre de fois où la page restitue le DOM sera réduit et l'efficacité sera considérablement améliorée.

var frag = document.createDocumentFragment() //创建一个虚拟节点对象	
for(var i = 0; i < 10; i++) {				
    var li = document.createElement("li")		
    li.innerHTML = &#39;我是第&#39; + i + 1 + &#39;个元素&#39;		
    frag.appendChild(li)  //将li元素加到虚拟节点对象上
    } 			
    ul.appendChild(frag)  //将虚拟节点对象加到ul上

Autres

1. Délégation d'événements, en utilisant les événements du navigateur et la capture de bulles pour réduire la liaison des événements de page, nous pouvons spécifier un. gestionnaire d'événements pour gérer tous les événements d'un certain type. Trop de fonctions d'événement occuperont beaucoup de mémoire, et plus il y aura d'éléments DOM liés à l'événement, plus le nombre de visites DOM augmentera, et le temps de préparation interactive de la page sera également retardé.

// 事件委托前
var lis = document.getElementsByTagName(&#39;li&#39;)
for(var i = 0; i < lis.length; i++) {
   lis[i].onclick = function() {
      console.log(this.innerHTML)
   }}    // 利用浏览器事件通过父元素委托事件给子元素
   var ul = document.getElementsByTagName(&#39;ul&#39;)ul.onclick = function(event) {
	//也可以做判断给指定的子元素绑定事件
   console.log(event.target.innerHTML)};

2. L'optimisation dans la boucle réduit le nombre d'opérations dom

//例子1:减少在计算过程中操作dom
// 优化前,访问了好多次dom,这些都是细节问题,有经验的绕过,小白平常多注意就行
for(var i = 0; i < 10; i++) {
    document.getElementById(&#39;el&#39;).innerHTML += &#39;1&#39;} 
    // 优化后 
    var str = &#39;&#39;for(var i = 0; i < 10; i++) {
    str += &#39;1&#39;}document.getElementById(&#39;el&#39;).innerHTML = str/

En regardant les choses de cette façon, vous ne pouvez pas ressentir l'effet de la longueur du nœud de cache. exemple ci-dessous

//不缓存
var ps = document.getElementsByTagName("p"), i, p;
for( i=0; i<ps.length; i++ ){  
    p = document.createElement("p");
    document.body.appendChild("p");
    }造成死循环,每次执行for循环都会动态获取ps的长度,而我们每次进入循环都增加了一个DOM(p),ps的长度也+1.
    //缓存
    var ps = document.getElementsByTagName("p"), i, p,len;
    for( i=0;len=ps.length;i<len; i++ ){  
        p = document.createElement("p");
        document.body.appendChild("p");
    }//使用变量保存ps的长度。

3. Différences dans les sélecteurs

Il existe deux manières les plus courantes d'obtenir des éléments, getElementsByXXX() et queryselectorAll() La différence entre ces deux sélecteurs. est très gros. Le premier consiste à obtenir une collection dynamique, et le second consiste à obtenir une collection statique

// 假设一开始有2个livar 
lis = document.getElementsByTagName(&#39;li&#39;)  // 动态集合
var ul = document.getElementsByTagName(&#39;ul&#39;)[0]
 for(var i = 0; i < 3; i++) {
    console.log(lis.length)
    var newLi = document.createElement(&#39;li&#39;)
    ul.appendChild(newLi)}// 输出结果:2, 3, 4
    // 优化后
    var lis = document.querySelectorAll(&#39;li&#39;)  // 静态集合 
    var ul = document.getElementsByTagName(&#39;ul&#39;)[0]
 for(var i = 0; i < 3; i++) {
    console.log(lis.length)
    var newLi = document.createElement(&#39;li&#39;)
    ul.appendChild(newLi)}// 输出结果:2, 2, 2

Le fonctionnement de la collection statique ne provoquera pas de nouvelle requête du document, qui est plus optimisé que la collection dynamique.

Apprentissage recommandé : Tutoriel vidéo javascript

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