O que há de tão ruim no DOM?

42

Continuo ouvindo pessoas (Crockford em particular) dizendo que o DOM é uma API terrível, mas não justificando realmente essa afirmação. Além das inconsistências entre navegadores, quais são algumas das razões pelas quais o DOM é considerado tão ruim?

wheresrhys
fonte
31
Apart from cross-browser inconsistenciesIsso não é suficiente?
yannis
3
A mesma pergunta (incluindo referência a Crockford) foi feita e encerrada como não construtiva na SO: O que há de errado com o DOM?
Gnat
3
A maioria das pessoas que dizem que o DOM é terrível ou são navegadores antigos ignorantes ou dizendo são terrível
Raynos
O modelo de propagação de eventos está incorreto: ele não permite que os nós pai substituam os manipuladores de eventos filhos para adicionar um comportamento personalizado. No POO, ele chamava funções virtuais, polimorfismo e delegação (herança através da composição). Os eventos são capturados de cima para baixo primeiro e depois borbulhados. No Elm, eles implementaram um modelo de composição muito adequado, onde os eventos borbulham primeiro e depois são "capturados" (propagados de pais para filhos). Permite cancelar eventos ("fechar uma janela?") E substituir / decorar o comportamento do componente filho.
Brian Haak

Respostas:

33

Crockford fez uma extensa apresentação intitulada "Uma API Inconveniente: A Teoria do Dom", onde ele explica mais ou menos suas opiniões sobre o DOM. É longo (1h 18m), mas como a maioria das apresentações de Crockford, é bastante agradável e educativo.

As inconsistências entre navegadores parecem ser sua principal preocupação, e eu concordo que é a coisa mais irritante do DOM. Ele identifica:

  • Armadilhas proprietárias (armadilhas para navegadores e servidores),
  • Quebra de regras,
  • Guerra corporativa,
  • Pressão extrema no tempo

como os principais problemas por trás das várias inconsistências, a adição de que apresentação, sessão ou interatividade nunca foi prevista na visão original da web. Alguns exemplos de inconsistências incluem:

  • document.all, um recurso exclusivo da Microsoft,
  • o fato de que namee idcostumava ser intercambiável.
  • as diferentes funções na recuperação de nós:
    • document.getElementById(id),
    • document.getElementsByName(name),
    • *node*.getElementsByTagName(tagName))

e continua com mais alguns exemplos, visando principalmente atravessar o DOM, vazamentos de memória e vazamentos de eventos. Há um slide de resumo, intitulado "As rachaduras do DOM", que resume:

  • A lista de erros do DOM inclui todos os erros no navegador.
  • A lista de erros do DOM inclui todos os erros em todos os navegadores suportados.
  • Nenhum DOM implementa completamente os padrões.
  • Grande parte do DOM não está descrito em nenhum padrão.

Em suma, é uma API bagunçada e bagunçada. Pode parecer difícil, mas você deve ter em mente que, quando está desenvolvendo para a Web, raramente escolhe o navegador que seus clientes usarão. Ter que testar tudo em pelo menos duas versões de cada um dos principais navegadores envelhece muito em breve. Uma API deve ser consistente e o DOM foi vítima das guerras dos navegadores , mas está melhorando. Ainda não é tão neutro em plataforma quanto o W3C (e acho que todos nós) gostaria que fosse, mas os fornecedores de navegadores parecem muito mais ansiosos para cooperar do que há cinco ou dez anos atrás.

yannis
fonte
18
a inconsistência entre navegadores não tem nada a ver com o DOM. É o que chamamos de "navegadores herdados". Não culpe o DOM pela existência de navegadores herdados. É como dizer "o linux é péssimo porque eu sei a distribuição herdada e eles são péssimos".
Raynos
document.allestá nos padrões
Raynos
@Raynos Sim e não. Os fornecedores de navegadores têm sido a principal força por trás da evolução dos padrões da web por muito tempo, estragando tudo, a analogia com o linux não suporta muito. O que estou tentando enfatizar é que o próprio DOM não está com defeito, são as implementações que estão com defeito e a maneira incoerente em que o padrão evoluiu. Tomemos, document.allpor exemplo, nos padrões, mas como uma violação intencional .
Yannis
1
Não posso me incomodar em falar sobre pessoas confundindo navegadores legados e o DOM. Deixei um comentário. Quanto aos navegadores herdados, deixar de fornecer suporte para eles é trivial, basta fazê-lo. Tenha as bolas para fazer isso. Você controla sua vida de desenvolvimento ou o IE8 a controla. Eu controlo o meu.
Raynos
3
Ótima resposta; outro aborrecimento que você não mencionou é que a API do DOM é extremamente detalhada - basta comparar o código jQuery típico para, por exemplo, inserir um elemento com alguns atributos em um nó específico versus uma versão simples do DOM que faz o mesmo.
Tdammers
15

O que há de errado com o DOM? Além da sintaxe inspirada em Java (na qual Crockford abordou), nada.

O que está "errado" se aplica parcialmente aos fornecedores de navegadores; o que está "errado" se aplica aos desenvolvedores; o que está "errado" se aplica à ignorância.

Então, por onde começar?

No buraco do coelho…

Fornecedores de navegadores

Primeiramente, os fornecedores de navegadores lutaram competitivamente ao longo de décadas para serem os "melhores", "mais rápidos", "mais fáceis" etc. Na primeira década (199x a 2000), a Microsoft dominou. O Internet Explorer introduziu idéias inovadoras, como:

  • expor o mecanismo de análise de HTML do navegador como innerHTMLe outerHTML;
  • fácil manipulação textual com innerTexte outerText;
  • um modelo de evento ( *tachEvent) que foi o modelo para DOM Nível 2 Eventos ( *EventListener).

Cada um deles contribuiu (para o bem e para o mal) significativamente para a pilha de desenvolvimento da web de hoje. O Opera chegou a implementar os três na versão 7 (2003).

No entanto, o Netscape tinha seu próprio modelo de evento DOM ( *EventListener). Em 2000, tornou-se a especificação de eventos de nível 2 do DOM. O Safari 1 (2003) implementou esse modelo; Opera 7 (2003) também implementou esse modelo. Quando as ruínas do Netscape se tornaram Mozilla, o Firefox 1 (2004) herdou o modelo.

Na primeira seção da segunda década (2000-2004), a Microsoft reinou suprema. O Internet Explorer 6 (2001) foi de longe o melhor navegador da época. Um de seus concorrentes, Opera 6 (2001), ainda não havia implementado o DOM Nível 1 Núcleo ( createElementet al.) Que a Microsoft o implementou no Internet Explorer 4 (1997) antes que a especificação se tornasse uma recomendação (1998).

No entanto, a segunda seção da segunda década (2004–2010) seria desastrosa para a Microsoft. Em 2003, a Apple lançou o Safari 1.0; em 2004, a Mozilla concluiu o Firefox 1.0. A Microsoft estava aparentemente dormindo no trono no topo da montanha dos navegadores. O Internet Explorer 7 não foi lançado até 2006: um intervalo de cinco anos que data da data de lançamento do Internet Explorer 6. Diferentemente das versões 4 a 6 do Internet Explorer, a versão 7 pouco inovava; As alterações do DOM foram mínimas. Quase dois anos e meio depois, o Internet Explorer 8 foi lançado. A Microsoft acordou do sono e notou a coalescência que outros fornecedores de navegadores haviam formado em torno de vários padrões da web. Infelizmente, passou muito tempo desde a última inovação real da Microsoft. Um movimento foi criado entre os fornecedores de navegadores. Novos recursos do DOM deveriam ser adicionados no formulário de especificação ao W3C; As idéias da Microsoft foram deixadas no passado. Modelo de evento da Microsoft (*tachEvent) foi evitado pelo modelo de eventos do nível 2 do DOM. O Internet Explorer não implementou o modelo anterior até a versão 9 (2011), que se tornou o modelo DOM Nível 3 Eventos.

As loucuras da Microsoft (DOM) podem ser resumidas pelos seguintes pontos:

  • presença como um recurso principal do Windows e os requisitos de segurança resultantes no nível do SO;

  • dependência de ActiveX para código do lado do cliente;

  • inovação que diminuiu curiosamente após a versão 6 (2001).


Desenvolvedores (Web)

Em segundo lugar, os desenvolvedores têm certa culpa. À medida que a web continua decolando, mais e mais pessoas estão se interessando pelo desenvolvimento da web. Isso levou a uma diluição do talento e da ética no trabalho. O problema, no entanto, reside principalmente na atitude. "Faça rápido" tem precedência sobre "Faça certo". Como resultado, inúmeras páginas da web são incompatíveis com vários navegadores. Uma das principais causas dessa incompatibilidade é uma prática chamada "user agent sniffing". Embora a prática ainda esteja em uso hoje em dia, ela foi provada como errônea e prejudicial. O Opera chegou ao ponto de "congelar" a versão do agente do usuário em "9.80" na versão 10 (2009) e além. O objetivo era impedir a quebra de scripts incorretos. Uma prática muito melhor chamada "


Ignorância

Terceiro, meu ponto de culpa preferido é a ignorância; desconhecimento do fato de que os fornecedores de navegadores não trabalharam juntos o suficiente para criar especificações unificadas; desconhecimento do fato de que a Microsoft evitou usuários de outros navegadores; desconhecimento do fato de que os desenvolvedores são preguiçosos ou míopes demais para se preocupar em pesquisar navegadores (especialmente aqueles que não estão em voga ). Existem muitas diferenças nas APIs e implementações. A maioria pode ser evitada com uma abordagem simplificada, porém defensiva (dependência do DOM 0), juntamente com grandes quantidades de pesquisas e testes. A ignorância levou à noção de que o Internet Explorer 6 é uma praga na Terra (lembre-se de seu lugar no trono do navegador mencionado anteriormente).


Reflexão

Infelizmente, o DOM é apenas uma API incompreendida. Muitos desejam jogar pedras (via FUD), mas poucos desejam aprender seus meandros. Um resultado dessa ignorância é a introdução dos "seletores" do DOM. O DOM no coração é uma API para manipular as árvores de documentos. A travessia de árvore deve ser usada para problemas complexos, dada a forma de um documento analisado. Com a introdução da API DOM Selectors, um desenvolvedor agora pode aproveitar o mecanismo de CSS do navegador. Isso é bastante conveniente, mas oculta a verdadeira forma de uma árvore de documentos. Com "seletores", a recuperação do nó do elemento é elementar. No entanto, o DOM possui onze outros tipos de nós especificados. O que dizer de nós de texto? Nós de comentários? Nós do documento? Esses também são nós frequentemente desejados ao interagir com o DOM.


Conclusão

Em resumo, não se apresse e leia as várias especificações do DOM. Teste o código no maior número possível de navegadores. Se o Internet Explorer parecer estar se comportando de maneira estranha, consulte o MSDN. Na maioria das vezes, o comportamento é documentado.

(Anedotas históricas podem e podem ser imprecisas; qualquer imprecisão pode ser levantada.)

—Matt

nulo
fonte
O Opera chegou ao ponto de "congelar" - eu odeio esse tipo de abordagem, pois é míope (alguns desenvolvedores não conseguem codificar, então vamos estragar a API para ajudá-los). Você geralmente precisa obter o tipo e a versão do navegador quando houver um bug específico no navegador que seu cliente insista em corrigir. A correção para um navegador específico é muito mais fácil do que implementar alguma "detecção de bug" (ou seja, o inverso da "detecção de recurso").
Pavel Horal
3

DOM é uma API terrível

Isso está errado . O DOM NÃO é uma API terrível.

  • Primeiro, lembre-se de que o DOM é independente de idioma. Todos os principais idiomas implementaram a API. Isso ocorre porque você simplesmente não o usa no navegador, mas em todos os lugares que precisa lidar com XML.

  • Segundo, observe que o DOM não define classes, mas interfaces. Isso tem uma implicação muito importante: as linguagens podem implementá-lo da maneira que combina com suas construções e filosofia. Isso libera todos os idiomas de serem consistentes na implementação com outros.

  • Terceiro, o DOM é uma das duas principais maneiras de analisar XML (sendo outro o SAX) e, dependendo do seu contexto, o DOM pode ser muito eficiente.

O que você está se referindo é o DOM do navegador. E eu concordo que o DOM "se sente" mal no navegador. Parte do motivo são incompatibilidades do navegador. Mas não concordo que eles sejam a única razão da má reputação do DOM no navegador.

  • Primeiro, se você pensar bem, o DOM é uma daquelas áreas em que essas incompatibilidades são relativamente mais fáceis de serem superadas. Em comparação, eventos, por exemplo, são muito mais complicados e irritantes para normalizar.

  • Segundo, a detecção de recursos do DOM é mais simples do que em outras áreas.

  • Terceiro, o DOM 3 é muito melhor - e hoje todos os navegadores suportam a maioria.

Certamente, as incompatibilidades são irritantes, mas quando você as aborda, o DOM é muito menos irritante.

Também discordo de razões como armadilhas proprietárias, guerra corporativa, etc.

  • Eu acho que é a desconexão entre a filosofia do JavaScript ser uma linguagem leve e a implementação do DOM inspirada no Java - que contribuiu para grande parte da frustração.

  • Em segundo lugar, o DOM foi projetado para XML e foi adaptado para HTML. Portanto, no navegador, temos exatamente dois DOMs - HTML DOM e XML DOM - e eles são incompatíveis.

  • Terceiro, a travessia do DOM no navegador não é boa. Não temos o XPath para HTML DOM, portanto, antes dos mecanismos seletores de CSS, era realmente entediante fazer travessias.

Finalmente, acho que hoje , com os navegadores modernos (e com os navegadores mais antigos desaparecendo lentamente), não há razão para o DOM ser chamado de ruim. Certamente vai melhorar no navegador - a API e a implementação.

codificador de árvore
fonte
eventos são tão triviais para normalizar: \
Raynos 6/12/12
pense sobre isso - se você tivesse que dar suporte à currentTargetpropriedade para o objeto de evento - seria trivial?
treecoder
implementação de subida do evento é como um 100 linhas de código: \
Raynos
currentTargetnão é apenas uma bolha de eventos - e seria realmente sensato implementar seu próprio bolha de eventos?
treecoder
1
E dataManagersentado lá fora, você diz que o código é trivial? :)
treecoder