¿Qué tiene de malo el DOM?

42

Sigo escuchando a la gente (Crockford en particular) decir que el DOM es una API terrible, pero no justifica realmente esta afirmación. Además de las inconsistencias entre navegadores, ¿cuáles son algunas de las razones por las cuales el DOM se considera tan malo?

Wheresrhys
fuente
31
Apart from cross-browser inconsistencies¿No es eso suficiente?
Yannis
3
La misma pregunta (incluida la referencia a Crockford) se ha formulado y cerrado como no constructiva en SO: ¿Qué tiene de malo el DOM?
mosquito
3
La mayoría de las personas que dicen que el DOM es terrible son ignorantes o dicen que los navegadores heredados son terribles
Raynos
El modelo de propagación de eventos es incorrecto: no permite que los nodos primarios anulen los controladores de eventos secundarios para agregar un comportamiento personalizado. En OOP llamó funciones virtuales, polimorfismo y delegación (herencia a través de la composición). Los eventos se capturan primero de arriba a abajo y luego se burbujean. En Elm han implementado un modelo composable muy adecuado donde los eventos burbujean primero y luego "capturados" (propagación de padres a hijos). Permite cancelar eventos ("¿cerrar una ventana?") Y anular / decorar el comportamiento del componente secundario.
Brian Haak

Respuestas:

33

Crockford ha dado una extensa presentación titulada "Una API incómoda: la teoría del Dom", donde explica más o menos sus opiniones sobre el DOM. Es largo (1h 18m), pero como la mayoría de las presentaciones de Crockford es bastante agradable y educativo.

Las inconsistencias de los navegadores cruzados parecen ser su principal preocupación, y estoy de acuerdo en que es lo más molesto del DOM. El identifica:

  • Trampas propietarias (trampas de navegador y servidor),
  • Desobediencia de las reglas,
  • Guerra corporativa,
  • Presión extrema de tiempo

Como los problemas clave detrás de las diversas inconsistencias, agregar esa presentación, sesión o interactividad nunca se anticipó en la visión original de la web. Algunos ejemplos de las inconsistencias incluyen:

  • document.all, una característica única de Microsoft,
  • el hecho de que namey idsolía ser intercambiable.
  • Las diferentes funciones en la recuperación de nodos:
    • document.getElementById(id),
    • document.getElementsByName(name),
    • *node*.getElementsByTagName(tagName))

y continúa con algunos ejemplos más, principalmente dirigidos a atravesar el DOM, pérdidas de memoria y eventos de goteo y burbujeo. Hay una diapositiva de resumen, titulada "The Cracks of DOM" que resume:

  • La lista de errores DOM incluye todos los errores en el navegador.
  • La lista de errores DOM incluye todos los errores en todos los navegadores compatibles.
  • Ningún DOM implementa completamente los estándares.
  • Gran parte del DOM no se describe en ningún estándar.

En resumen, es una API desordenada, desordenada. Puede parecer una trampa, pero debe tener en cuenta que cuando desarrolla para la web, rara vez puede elegir el navegador que usarán sus clientes. Tener que probar todo en al menos dos versiones de cada uno de los principales navegadores envejece muy pronto. Se supone que una API es consistente y el DOM fue víctima de las guerras del navegador , pero está mejorando. Todavía no es tan neutral para la plataforma como le gustaría al W3C (y creo que a todos nosotros), pero los proveedores de navegadores parecen mucho más ansiosos por cooperar que hace cinco o diez años.

Yannis
fuente
18
La inconsistencia entre navegadores no tiene nada que ver con el DOM. Eso es lo que llamamos "navegadores heredados". No culpe al DOM por la existencia de navegadores heredados. Eso es como decir "Linux apesta porque conozco la distribución heredada ym y apestan".
Raynos
document.allestá en los estándares
Raynos
@Raynos Sí y no. Los proveedores de navegadores han sido la fuerza principal detrás de la evolución de los estándares web durante demasiado tiempo, lo han estropeado todo, la analogía con Linux no tiene mucha importancia. Lo que estoy tratando de enfatizar es que el DOM en sí no es defectuoso, son las implementaciones las que son defectuosas y la forma incoherente en que evolucionó el estándar. Tomemos document.allpor ejemplo, está en los estándares pero como una violación intencional .
Yannis
1
No puedo molestarme en hablar sobre las personas que confunden los navegadores heredados y el DOM. Dejé un comentario En cuanto a los navegadores heredados, dejar de admitirlos es trivial, solo hazlo. Ten las bolas para hacerlo. O controlas tu vida de desarrollo o IE8 lo controla. Yo controlo el mío.
Raynos
3
Gran respuesta; Otra molestia que no ha mencionado es que la API DOM es extremadamente detallada: simplemente compare el código típico de jQuery para, digamos, insertar un elemento con algunos atributos en un nodo en particular frente a una versión DOM simple que hace lo mismo.
tdammers
15

¿Qué le pasa al DOM? Aparte de la sintaxis inspirada en Java (que Crockford ha mencionado), nada.

Lo que está "incorrecto" se aplica parcialmente a los proveedores de navegadores; lo que está "mal" se aplica a los desarrolladores; lo que está "mal" se aplica a la ignorancia.

Entonces, ¿por dónde empezar?

Por la madriguera del conejo…

Proveedores de navegadores

En primer lugar, los proveedores de navegadores han luchado competitivamente durante décadas para ser los "mejores", "más rápidos", "más fáciles", etc. En la primera década (199x-2000), Microsoft gobernó el gallinero. Internet Explorer introdujo ideas innovadoras como:

  • exponiendo el motor de análisis HTML del navegador como innerHTMLy outerHTML;
  • fácil manipulación textual con innerTexty outerText;
  • un modelo de evento ( *tachEvent) que fue el modelo para los eventos DOM Nivel 2 ( *EventListener).

Cada uno ha contribuido (para bien o para mal) significativamente a la pila de desarrollo web actual. Opera incluso llegó a implementar los tres en la versión 7 (2003).

Sin embargo, Netscape tenía su propio modelo de evento DOM ( *EventListener). En 2000, se convirtió en la especificación DOM Nivel 2 Eventos. Safari 1 (2003) implementó este modelo; Opera 7 (2003) también implementó este modelo. Cuando las ruinas de Netscape se convirtieron en Mozilla, Firefox 1 (2004) heredó el modelo.

Para la primera sección de la segunda década (2000-2004), Microsoft reinó supremo. Internet Explorer 6 (2001) era, de lejos, el mejor navegador de la época. Uno de sus competidores, Opera 6 (2001), aún no había implementado el DOM Level 1 Core ( createElementet al.) Microsoft lo implementó en Internet Explorer 4 (1997) antes de que la especificación se convirtiera en una recomendación (1998).

Sin embargo, la segunda sección de la segunda década (2004-2010) resultaría desastrosa para Microsoft. En 2003, Apple lanzó Safari 1.0; en 2004, Mozilla completó Firefox 1.0. Microsoft aparentemente estaba dormido en su trono en la cima de la montaña del navegador. Internet Explorer 7 no se lanzó hasta 2006: una brecha de cinco años que se remonta a la fecha de lanzamiento de Internet Explorer 6. A diferencia de las versiones de Internet Explorer 4 a 6, la versión 7 innovaba poco; Los cambios DOM fueron minutos. Casi dos años y medio después, se lanzó Internet Explorer 8. Microsoft se había despertado de su sueño y notó la unión de otros proveedores de navegadores en torno a numerosos estándares web. Desafortunadamente, había pasado demasiado tiempo desde la última innovación real de Microsoft. Se había creado un movimiento entre los vendedores de navegadores. Se agregarían nuevas características DOM en forma de especificación al W3C; Las ideas de Microsoft quedaron en el pasado. Modelo de evento de Microsoft (*tachEvent) se evitó para el modelo DOM Nivel 2 Eventos. Internet Explorer no implementó el modelo anterior hasta la versión 9 (2011), que se convirtió en el modelo DOM Nivel 3 Eventos.

Las locuras de Microsoft (DOM) se pueden resumir en los siguientes puntos:

  • presencia como una característica central de Windows, y los requisitos de seguridad a nivel del sistema operativo resultantes;

  • dependencia de ActiveX para el código del lado del cliente;

  • innovación que disminuyó curiosamente después de la versión 6 (2001).


(Desarrolladores de sitios de Internet

En segundo lugar, los desarrolladores tienen cierta culpa. A medida que la web continúa despegando, más y más personas están "incursionando" en el desarrollo web. Esto había llevado a una dilución en talento y ética de trabajo. El problema, sin embargo, radica principalmente en la actitud. "Hacerlo rápido" ha prevalecido sobre "Hacerlo bien". Como resultado, innumerables páginas web son incompatibles con varios navegadores. Una de las principales causas de esta incompatibilidad es una práctica llamada "detección de agentes de usuario". Aunque la práctica todavía se usa en la actualidad, se ha demostrado que es errónea y dañina. Opera incluso llegó a "congelar" la versión del agente de usuario en "9.80" en la versión 10 (2009) y más allá. Esto tenía la intención de evitar que los scripts erróneos se rompieran. Una práctica mucho mejor llamada "


Ignorancia

En tercer lugar, mi punto de culpa preferido es la ignorancia; ignorancia en el hecho de que los proveedores de navegadores no trabajaron juntos lo suficiente como para crear especificaciones unificadas; ignorancia en el hecho de que Microsoft rechazó a los usuarios de otros navegadores; ignorancia en el hecho de que los desarrolladores son demasiado flojos o demasiado miopes para molestarse en buscar navegadores (especialmente aquellos que no están de moda ). Existen muchas diferencias en las API y las implementaciones. La mayoría se puede evitar con un enfoque simplificado pero defensivo (dependencia del DOM 0) junto con grandes cantidades de investigación y pruebas. La ignorancia ha llevado a la noción de que Internet Explorer 6 es una plaga en la Tierra (recuerde su lugar en el trono del navegador mencionado anteriormente).


Reflexión

Lamentablemente, el DOM es solo una API incomprendida. Muchos desean arrojar piedras (a través de FUD), pero pocos desean aprender sus complejidades. Un resultado de esta ignorancia es la introducción de "selectores" DOM. El DOM en el fondo es una API para manipular árboles de documentos. El recorrido del árbol debe usarse para problemas complejos dada la forma de un documento analizado. Con la introducción de la API de Selectores DOM, un desarrollador ahora puede aprovechar el motor transversal CSS del navegador. Esto es bastante conveniente, pero oculta la verdadera forma de un árbol de documentos. Con "selectores", la recuperación del nodo del elemento es elemental. Sin embargo, el DOM tiene otros once tipos de nodos especificados. ¿Qué pasa con los nodos de texto? Nodos de comentarios? Nodos de documento? Estos también son nodos que a menudo se desean al interactuar con el DOM.


Conclusión

En resumen, tómese su tiempo y lea las diversas especificaciones DOM. Pruebe el código en tantos navegadores como sea posible. Si se percibe que Internet Explorer se comporta de manera extraña, consulte a MSDN. Muy a menudo, el comportamiento está documentado.

(Las anécdotas históricas pueden y pueden ser inexactas; cualquier inexactitud es bienvenida).

-Mate

nulo
fuente
Opera incluso llegó a "congelarse" : odio este tipo de enfoque, ya que es bastante miope (algunos desarrolladores no pueden codificar, así que arruinemos la API para ayudarlos). Por lo general, necesita obtener el tipo y la versión del navegador cuando hay un error específico en ese navegador que su cliente insiste en corregir. La corrección para un navegador específico es mucho más fácil que implementar alguna "detección de errores" (es decir, al revés de "detección de características").
Pavel Horal
3

DOM es una API terrible

Eso está mal . DOM NO es una API terrible.

  • Primero, recuerde que DOM es independiente del lenguaje. Todos los idiomas principales han implementado la API. Esto se debe a que simplemente no lo usa en el navegador, pero en todas partes debe tratar con XML.

  • En segundo lugar, tenga en cuenta que DOM no define clases sino interfaces. Esto tiene una implicación muy importante: los idiomas pueden implementarlo de la manera que se adapte a sus construcciones y filosofía. Esto libera a todos los idiomas de tener que ser consistentes en la implementación con otros.

  • Tercero, DOM es una de las dos formas principales de analizar XML (otro es SAX), y dependiendo de su contexto, DOM puede ser muy eficiente.

A lo que se refiere es al navegador DOM. Y, estoy de acuerdo en que DOM "se siente" mal en el navegador. Parte de la razón son las incompatibilidades del navegador. Pero no estoy de acuerdo con que sean la única razón de la mala reputación de DOM en el navegador.

  • Primero, si lo piensa, DOM es una de esas áreas donde estas incompatibilidades son relativamente más fáciles de superar. En comparación, los eventos, por ejemplo, son engañosos y molestos de normalizar.

  • En segundo lugar, la detección de características para las características DOM es más simple que para otras áreas.

  • En tercer lugar, DOM 3 es mucho mejor, y hoy todos los navegadores son compatibles con la mayoría.

Ciertamente, las incompatibilidades son molestas, pero cuando se llega a ellas, el DOM es mucho menos irritante.

También estoy en desacuerdo con razones como trampas patentadas, guerra corporativa, etc., que son la razón de ello.

  • Creo que es la desconexión entre la filosofía de JavaScript de ser un lenguaje liviano y la implementación de DOM inspirado en Java, lo que ha contribuido a gran parte de la frustración.

  • En segundo lugar, DOM se ha diseñado para XML y se ha adaptado para HTML. Por lo tanto, en el navegador, tenemos exactamente dos DOM: HTML DOM y XML DOM, y son incompatibles.

  • Tercero, el recorrido DOM en el navegador no es bueno. No tenemos XPath para HTML DOM, por lo que antes de los motores de selección CSS, era realmente tedioso hacer recorridos.

Finalmente, creo que hoy , con los navegadores modernos (y con los navegadores más antiguos que se desvanecen lentamente), no hay ninguna razón por la que DOM deba llamarse malo. Ciertamente va a mejorar en el navegador, tanto la API como la implementación.

codificador de árboles
fuente
los eventos son igual de triviales para normalizar: \
Raynos
currentTargetpiénselo , si tuviera que soportar la propiedad para el objeto de evento, ¿sería trivial?
treecoder
implementar burbujeo de eventos es como 100 líneas de código: \
Raynos
currentTargetno es solo burbujeo de eventos, y ¿sería realmente inteligente implementar su propio burbujeo de eventos?
codificador de árbol
1
¿Y con dataManagersentarse afuera, dices que el código es Trivial? :)
treecoder