w3schools variable tutorial modificar getelement javascript dom

javascript - variable - ¿Pero por qué el DOM del navegador sigue siendo tan lento después de 10 años de esfuerzo?



modificar dom javascript (3)

El navegador web DOM ha existido desde finales de los años 90, pero sigue siendo una de las mayores limitaciones en rendimiento / velocidad.

Tenemos algunas de las mentes más brillantes del mundo de Google, Mozilla, Microsoft, Opera, W3C y varias otras organizaciones que trabajan en tecnologías web para todos nosotros, así que obviamente no es un simple "Oh, no lo optimizamos " problema.

Mi pregunta es si debería trabajar en la parte de un navegador web que trata específicamente con esto, ¿por qué me sería tan difícil hacer que funcione más rápido?

Mi pregunta no es what es what hace que sea lenta, sino que pregunta why no se ha vuelto más rápida.

Esto parece ir en contra de lo que sucede en otros lugares, como los motores JS con un rendimiento cercano al del código C ++.

Ejemplo de secuencia de comandos rápida:

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

Ejemplo de lento debido a DOM:

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

Algunos detalles según solicitud:

Después del marcado de banco, parece que no es un problema lento sin solución, pero a menudo se usa la herramienta incorrecta, y la herramienta utilizada depende de lo que se hace entre navegadores.

Parece que la eficiencia DOM varía mucho entre los navegadores, pero mi presunción original de que el dom es lento e irresoluble parece estar equivocado.

Ejecuté pruebas contra Chrome, FF4 e IE 5-9, puede ver las operaciones por segundo en este gráfico:

Chrome es increíblemente rápido cuando usas la DOM API, pero es mucho más lento usando el operador .innerHTML (por una magnitud 1000 veces más lenta), sin embargo, FF es peor que Chrome en algunas áreas (por ejemplo, la prueba de agregar es mucho más lenta que Chrome), pero la prueba InnerHTML se ejecuta mucho más rápido que Chrome.

IE parece estar empeorando al usar DOM append y mejor en innerHTML a medida que avanzas en las versiones desde 5.5 (es decir, 73ops / seg en IE8 ahora a 51 ops / seg en IE9).

Tengo la página de prueba aquí:

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

Lo que es interesante es que parece que diferentes navegadores parecen tener diferentes desafíos cuando generan el DOM. ¿Por qué hay tanta disparidad aquí?


Cuando cambias algo en el DOM puede tener innumerables efectos secundarios relacionados con el cálculo de diseños, hojas de estilo, etc.

Esta no es la única razón: cuando establece element.innerHTML=x , ya no se trata de las variables comunes de "almacenar un valor aquí", sino de objetos especiales que actualizan una carga de estado interno en el navegador cuando los establece.

Las implicaciones completas de element.innerHTML=x son enormes. Visión aproximada:

  • analizar x como HTML
  • pedir permiso al navegador
  • destruir nodos secundarios existentes de element
  • crear nodos secundarios
  • volver a calcular los estilos que se definen en términos de relaciones padre-hijo
  • volver a calcular las dimensiones físicas de los elementos de la página
  • notificar las extensiones del navegador del cambio
  • actualizar las variables Javascript que son identificadores de los nodos DOM reales

Todas estas actualizaciones deben pasar por una API que puentea Javascript y el motor HTML. Una razón por la que Javascript es tan rápido en estos días es que lo compilamos con un lenguaje más rápido o incluso con un código de máquina, ocurren muchas optimizaciones porque el comportamiento de los valores está bien definido. Al trabajar con DOM API, nada de esto es posible. Las aceleraciones en otros lugares han dejado atrás al DOM.


El autor original de la prueba es Hixie ( http://nontroppo.org/timer/Hixie_DOM.html ).

Este problema ha sido discutido en aquí y Connect (bug-tracker) también. Con IE10, el problema está resuelto. Resuelto, quiero decir que se han movido parcialmente a otra forma de actualizar DOM.

El equipo de IE parece manejar la actualización DOM similar al equipo Excel-macros en Microsoft, donde se considera una práctica deficiente actualizar las celdas activas en la hoja. Se supone que usted, el desarrollador, debe llevar a cabo la tarea de levantar objetos pesados ​​fuera de línea y luego actualizar el equipo en vivo por lotes. En IE se supone que debes hacer eso usando document-fragment (en lugar de documento). Con los nuevos estándares emergentes de ECMA y W3C, los fragmentos de documentos se deprecian. Entonces, el equipo de IE ha hecho un buen trabajo para contener el problema.

Les tomó algunas semanas desmontarlo de ~ 42,000 ms en IE10-ConsumerPreview a ~ 600 ms IE10-RTM . Pero les costó mucho esfuerzo sacarles la mano para convencerlos de que esto ES un problema. Su reclamo fue que no hay un ejemplo del mundo real que tenga 10,000 actualizaciones por elemento. Dado que el alcance y la naturaleza de las aplicaciones de Internet sofisticadas (RIA) no pueden predecirse, es vital tener un rendimiento cercano a los otros navegadores de la liga. Aquí hay otra toma de DOM por OP en MS Connect (en comentarios):

Cuando busco http://nontroppo.org/timer/Hixie_DOM.html , toma ~ 680ms y si guardo la página y la ejecuto localmente, ¡toma ~ 350ms!

Lo mismo ocurre si utilizo el evento button-onclick para ejecutar el script (en lugar de body-onload). Compare estas dos versiones:

jsfiddle.net/uAySs/ <- body onload

vs.

jsfiddle.net/8Kagz/ <- button onclick

Casi 2 veces la diferencia ...

Aparentemente, el comportamiento subyacente de onload y onclick varía también. Puede ser aún mejor en futuras actualizaciones.


En primer lugar, cualquier cosa que haga al DOM podría ser un cambio visible para el usuario. Si cambia el DOM, el navegador tiene que volver a establecer todo. Podría ser más rápido, si el navegador almacena en caché los cambios, solo establece cada X ms (suponiendo que ya no lo haga), pero tal vez no exista una gran demanda de este tipo de características.

En segundo lugar, innerHTML no es una operación simple. Es un truco sucio que empujó MS, y otros navegadores adoptaron porque es muy útil; pero no es parte del estándar (IIRC). Usando innerHTML, el navegador tiene que analizar la cadena y convertirla en un DOM. El análisis es difícil.