Profonde clonage vs réglage de innerHTML: quel est le plus rapide?
Je suis à essayer de comprendre les plus performantes moyen de profondeur de clonage d'une arborescence DOM dans le navigateur.
Si je démarre avec
var div = document.getElementById("source");
var markup = div.innerHTML;
Ce sera plus rapide,
var target = div.cloneNode(true);
ou
var target = document.cloneNode(false);
target.innerHTML = markup;
Je comprends la plateforme de navigateur peut faire une grande différence ici, donc toute information sur comment ces comparer dans le monde réel serait appréciée.
- Je ne comprends pas ce que vous cherchez. Vous voulez cloner un élément?
var target = div.cloneNode(true);
fait juste cela. Quel est le clonage d'avoir à faire avecinnerHTML
? - Les résultats spécifiques dépendra de votre navigateur, mais j'ai trouvé deux tests pertinents à jsPerf ici et ici.
- innerHTML détruit les écouteurs d'événement, ne l'utilisez pas.
Vous devez vous connecter pour publier un commentaire.
Testons!
J'ai ajouté le code suivant à une copie de StackOverflow Questions de la page (la suppression de scripts d'abord, et en cours d'exécution à partir de zéro avec l'un des timeit()s décommenté chaque fois, trois séries de 100 ops:
Voici les résultats en cours d'exécution sur une VirtualBox sur un Core 2 Q9300:
Donc cloneNode(true) est beaucoup plus rapide que la copie innerHTML. Bien sûr, il a toujours été va être; serialising un DOM de texte, puis ré-analyse de HTML est de travailler dur. La raison DOM opérations enfants sont généralement lent, c'est que vous êtes de l'insertion ou de les déplacer un par un; tous-at-once DOM opérations comme cloneNode ne pas avoir à le faire.
Safari parvient à faire le innerHTML op étonnamment rapidement, mais toujours pas presque aussi rapidement qu'il ne cloneNode. C'est à dire est, comme prévu, un chien.
Donc, l'auto-1s tout rond pour tout le monde qui a dit innerHTML serait Évidemment plus Vite sans tenir compte de ce que la question était en fait en train de faire.
Et oui, jQuery utilise innerHTML à cloner. Pas parce que c'est plus rapide si — lire la source:
jQuery utilise l'Élément.attachEvent() pour mettre en place son propre système d'événement, alors, naturellement, c'est pour éviter ce bug. Si vous n'en avez pas besoin, vous pouvez éviter la surcharge.
[Hors-sujet à part: encore une fois, je pense que la tenue de jQuery comme le summum de bonnes Pratiques peut être un peu erronée, compte tenu notamment de la ligne suivante:
Que le droit de jQuery ajoute son propre arbitraire des attributs aux éléments HTML, et puis il faut se débarrasser d'eux quand il les clones (ou sinon donne accès à leur balisage, par exemple, $().html() la méthode). C'est assez laid, mais il pense que la meilleure façon de le faire est le traitement de HTML à l'aide de l'expression régulière, qui est le genre d'erreur de base que vous attendez plus de naïf 1-réputation AFIN de questionneurs que l'auteur de la Seconde Venue du Meilleur JS Cadre Evar.
Espère que vous n'avez pas la chaîne “jQuery1="2"” n'importe où dans votre contenu texte, 'cos si donc vous avez juste a mystérieusement perdu. Grâce jQuery! Ainsi se termine le hors-sujet de côté.]
removeAttr()
sur elle? C'est peut-être un compromis, il pourrait être beaucoup plus rapide au détriment de la déformation toute personne qui utilise cette chaîne. Bien que cela soit rare, il devrait y avoir une sorte d'avertissement dans le jQuery docs (je ne l'ai pas trouvé si il y a)innerHTML
. Le choix deelementnode.jQueryId45438= [1]
(un objet Array) permettrait de jQuery pour mettre son ID unique sur l'élément sans perturber le fonctionnement de la sérialisation et exigeant post-innerHTML
corrections.jQuery.cache
) pour obtenir des données associées. La gestion des événements repose sur un type de données associée, donc à peu près chaque script jQuery est l'utilisation de ce.Hmmm... il est intéressant, je viens de faire un test de Firefox 3, et une profonde clone semble être environ 3 fois plus rapide que d'aller le innerHTML de l'itinéraire.
Je suis sûr que innerHTML est encore plus rapide que personne DOM opérations, mais au moins de profondeur de clonage, cloneNode(true) semble être mieux optimisé.