51 votes

Mais pourquoi le navigateur DOM est-il toujours aussi lent après 10 ans d'effort?

Le navigateur web DOM a été autour depuis la fin des années '90, mais cela reste l'une des plus grandes contraintes de performance et de vitesse.

Nous avons certains des plus brillants esprits de Google, Mozilla, Microsoft, Opera, W3C, et de diverses autres organisations qui travaillent sur des technologies web pour nous tous, alors, évidemment, ce n'est pas un simple "Oh, nous n'avons pas l'optimiser" la question.

Ma question est si je devais travailler sur le le cadre d'un navigateur web qui traite spécifiquement de ce sujet, pourquoi aurais-je tant de mal à le faire fonctionner plus vite?

Ma question n'est pas de demander ce qui le rend lent, c'est demander pourquoi n'est-elle pas devenir plus rapide?

Cela semble être à contre-courant de ce qui se passe ailleurs, comme JS moteurs avec une performance proche de celle du code C++.

Exemple de script vite fait:

for (var i=0;i<=10000;i++){
    someString = "foo";
}

Exemple de la lente en raison de DOM:

for (var i=0;i<=10000;i++){
    element.innerHTML = "foo";
}

Certains détails de la demande:

Après le bench-marking, on dirait qu'il n'est pas insoluble lent problème, mais souvent de la mauvaise utilisation de l'outil et de l'outil utilisé dépend de ce que vous êtes en train de faire de la cross-browser.

Il ressemble à la DOM l'efficacité varie considérablement entre les navigateurs, mais mon origine présomption que le dom est lente et irrémédiable semble être erronée.

J'ai couru des tests par rapport à Chrome, FF4, et IE 5-9, vous pouvez voir les opérations par seconde dans ce graphique:

enter image description here

Chrome est rapide comme l'éclair lorsque vous utilisez l'API DOM, mais bien plus lente en utilisant le .innerHTML de l'opérateur (par un séisme de magnitude 1000 fois plus lent), cependant, FF est pire que le Chrome dans certains domaines (par exemple, l'ajout de test est beaucoup plus lent que Chrome), mais le InnerHTML de test s'exécute beaucoup plus rapidement que le chrome.

IE semble effectivement être pire à l'aide de DOM ajouter et mieux à même de innerHTML comme vous le progrès à travers les versions depuis la version 5.5 (c'est à dire, 73ops/sec dans IE8 maintenant à 51 ops/sec dans IE9).

J'ai la page de test par ici:

http://jsperf.com/browser-dom-speed-tests2

Ce qui est intéressant, c'est qu'il semble que les différents navigateurs semblent tous avoir différents défis lors de la génération du DOM. Pourquoi une telle disparité ici?

57voto

spraff Points 10492

Lorsque vous modifiez un élément dans le DOM, il peut avoir une myriade d'effets secondaires à voir avec le recalcul des mises en page, les feuilles de style, etc.

Ce n'est pas la seule raison: lorsque vous définissez element.innerHTML=x vous n'êtes plus à l'ordinaire "de stocker une valeur ici" des variables, mais avec des objets spéciaux dont la mise à jour d'une charge de l'état interne dans le navigateur lorsque vous définissez.

L'ensemble des implications de la element.innerHTML=x sont énormes. Aperçu:

  • parse x HTML
  • poser des extensions de navigateur pour l'autorisation
  • détruire existant nœuds enfants de l' element
  • créer des nœuds enfants
  • recalculer les styles qui sont définis en termes de relations parent-enfant
  • recalculer les dimensions physiques des éléments de la page
  • informer les extensions de navigateur de le changer
  • mise à jour des variables Javascript, qui sont des poignées de véritables nœuds DOM

Toutes ces mises à jour doivent passer par une API qui permet de combler le Javascript et le HTML moteur. Une des raisons est que Javascript est si vite ces jours-ci, c'est que nous le compiler pour une plus rapide de la langue ou du même code machine, masses d'optimisations se produire parce que le comportement de ces valeurs n'est bien définies. Lorsque vous travaillez par le biais de l'API DOM, aucun de ce qui est possible. Accélérations d'ailleurs ont quitté le DOM derrière.

4voto

wisty Points 4280

Tout d'abord, tout ce que vous faites à la cathédrale pourrait être un utilisateur de changement visible. Si vous modifiez les DOM, le navigateur a à jeter le tout à nouveau. Il pourrait être plus rapide, si le navigateur met en cache les modifications, puis seulement dispose de toutes les X ms (en supposant qu'il ne veut pas le faire déjà), mais peut-être il n'y a pas une énorme demande pour ce genre de fonctionnalité.

Deuxièmement, innerHTML n'est pas une opération simple. C'est un sale hack que MS a poussé, et les autres navigateurs adopté parce qu'il est si utile; mais il ne fait pas partie de la norme (IIRC). En utilisant innerHTML, le navigateur doit analyser la chaîne, et de le convertir à un DOM. L'analyse est difficile.

4voto

vulcan raven Points 8312

Origine du test de l'auteur est Hixie (http://nontroppo.org/timer/Hixie_DOM.html).

Ce problème a été discuté sur StackOverflow ici et Connectez-vous (bug tracker) ainsi. Avec IE10, le problème est résolu. Par résolu, je veux dire qu'ils ont partiellement déplacé à un autre mode de mise à jour des DOM.

IE équipe semble gérer les DOM mise à jour similaire à Excel-les macros de l'équipe de Microsoft, où il est considéré comme une mauvaise pratique pour mettre à jour le live-cellules sur la feuille. Vous, le développeur, est censé prendre le levage lourd tâche en mode hors connexion, puis mise à jour de l'équipe live dans le lot. Dans IE que vous êtes censé faire qu'à l'aide de document-fragment (par opposition au document). Avec l'émergence de nouvelles ECMA et les normes W3C, document-frags sont amortis. Si IE équipe a fait un joli travail pour contenir le problème.

Il leur a fallu quelques semaines pour la bande vers le bas à partir de ~de 42 000 ms dans IE10-ConsumerPreview à ~600 ms IE10-RTM. Mais il a fallu beaucoup de jambe en tirant à les convaincre que c'EST un problème. Leur demande d'asile est qu'il n'existe aucun exemple réel qui a 10 000 mises à jour par élément. Étant donné que la portée et la nature des rich internet applications (Ria) ne peut pas être prédit, son essentiel d'avoir des performances proches des autres navigateurs de la ligue. Voici une autre de prendre sur la cathédrale par l'OP sur MS Connecter (dans les commentaires):

Quand je navigue à http://nontroppo.org/timer/Hixie_DOM.htmlil prend ~680 ms et si je enregistrez la page et de l'exécuter localement, il faut ~350ms!

Même chose si j'utilise le bouton-événement onclick pour exécuter le script (au lieu de corps-onload). Comparer ces deux versions:

jsfiddle.net/uAySs/ <-- body onload

vs

jsfiddle.net/8Kagz/ <-- bouton onclick

Presque 2x différence..

Apparemment, le problème sous-jacent de onload et onclick varie également. Il peut encore s'améliorer dans les prochaines mises à jour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X