JavaScript Limiter les mises à jour DOM


Exemple

Une erreur courante rencontrée dans JavaScript lors de l'exécution dans un environnement de navigateur est la mise à jour du DOM plus souvent que nécessaire.

Le problème ici est que chaque mise à jour de l’interface DOM oblige le navigateur à restituer l’écran. Si une mise à jour modifie la disposition d'un élément dans la page, la mise en page entière doit être recalculée, ce qui est très lourd en termes de performances, même dans les cas les plus simples. Le processus de redéfinition d'une page est connu sous le nom de redistribution et peut ralentir l'exécution d'un navigateur ou même ne pas répondre.

La conséquence de la mise à jour trop fréquente du document est illustrée par l'exemple suivant d'ajout d'éléments à une liste.

Considérez le document suivant contenant un élément <ul> :

<!DOCTYPE html>
<html>
    <body>
        <ul id="list"></ul>
    </body>
</html>

Nous ajoutons 5000 éléments à la liste en boucle 5000 fois (vous pouvez essayer cela avec un plus grand nombre sur un ordinateur puissant pour augmenter l'effet).

var list = document.getElementById("list");
for(var i = 1; i <= 5000; i++) {             
    list.innerHTML += `<li>item ${i}</li>`;  // update 5000 times
}

Dans ce cas, les performances peuvent être améliorées en regroupant les 5 000 modifications dans une seule mise à jour du DOM.

var list = document.getElementById("list");
var html = "";
for(var i = 1; i <= 5000; i++) {
    html += `<li>item ${i}</li>`;
}
list.innerHTML = html;     // update once

La fonction document.createDocumentFragment() peut être utilisée comme un conteneur léger pour le code HTML créé par la boucle. Cette méthode est légèrement plus rapide que la modification de la propriété innerHTML l'élément conteneur (comme illustré ci-dessous).

var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 1; i <= 5000; i++) {
    li = document.createElement("li");
    li.innerHTML = "item " + i;
    fragment.appendChild(li);
    i++;
}
list.appendChild(fragment);