O DOM virtual é uma representação leve em JavaScript do Modelo de Objeto de Documentos (em inglês, "Document Object Model" ou apenas "DOM"), utilizada em frameworks web declarativos como React, Vue.js e Elm. Como a geração de um DOM virtual é relativamente rápida, esses frameworks podem renderizá-lo quantas vezes forem necessárias a um custo computacional relativamente baixo. Em seguida, o framework compara o estado anterior e o atual do DOM virtual (diffing) e aplica apenas as alterações necessárias ao DOM real (reconciliação). Embora seja tecnicamente mais lento do que manipular o DOM diretamente com JavaScript puro, esse padrão simplifica o desenvolvimento de interfaces dinâmicas, já que o markup (geralmente HTML) fica diretamente vinculado ao estado da aplicação.

Técnicas semelhantes incluem o Glimmer, do Ember.js, e o Incremental DOM, do Angular.

História A API de DOM em JavaScript sempre foi inconsistente entre navegadores, difícil de usar e pouco escalável para projetos grandes. Bibliotecas como o jQuery surgiram para melhorar a consistência e a ergonomia da manipulação do HTML, mas ainda resultavam em código repetitivo que separava a lógica do markup e não descrevia claramente as mudanças realizadas.

O lançamento do AngularJS em 2010 marcou uma grande mudança no paradigma de interação entre JavaScript e HTML, introduzindo o conceito de dirty checking (em tradução livre, "checagem suja"). Em vez de criar e destruir manualmente ouvintes de eventos (do inglês, "event listeners") e modificar nós (do inglês, "nodes") do DOM, o AngularJS rastreava as mudanças em variáveis e renderizava novamente partes do DOM automaticamente quando algum valor em seu escopo era alterado. Esse ciclo de digestão permitia escrever código mais declarativo, integrando lógica e interface de forma mais natural.

Apesar disso, o AngularJS ainda exigia que os dados fossem explicitamente vinculados e observados no DOM, o que gerava preocupações de desempenho devido ao custo de verificar centenas de variáveis. Para resolver esse tipo de problema, o React foi a primeira grande biblioteca a adotar o DOM virtual, em 2013. Essa abordagem eliminou gargalos de desempenho, já que o processo de diffing e reconciliação era relativamente leve, e também simplificou o vínculo entre dados e interface, pois todos os componentes passaram a ser tratados como objetos. O React também introduziu o JSX, uma extensão de sintaxe semelhante ao XML que integra ainda mais o HTML com o JavaScript.

Com o sucesso do React, diversos frameworks adotaram a mesma ideia de uma representação ideal do DOM em memória. Entre eles, o Vue.js em 2014, que passou a utilizar um compilador de templates em vez do JSX e implementar reatividade granular de forma nativa.

Nos últimos tempos, o DOM virtual passou a ser criticado por questões de desempenho, devido ao tempo adicional necessário para o diffing e a reconciliação de nós do DOM. Isso levou ao surgimento de frameworks que não utilizam um DOM virtual, como o Svelte, e de outros que modificam o DOM diretamente, como o Angular 2.

Implementações

React

O React foi o pioneiro no uso de um DOM virtual para criar componentes de forma declarativa. Os nós desse DOM virtual são construídos com a função createElement(), mas normalmente são transpilados a partir de JSX para tornar o desenvolvimento mais ergonômico. Em componentes funcionais com hooks, o valor retornado pela função serve diretamente como o markup da página.

Vue.js O Vue.js também utiliza o DOM virtual para lidar com mudanças de estado, mas geralmente de forma mais transparente para o desenvolvedor. Um compilador de templates converte o HTML em nós do DOM, virtual como parte da implementação interna. Embora o Vue ofereça suporte a JSX e funções de renderização personalizadas, é mais comum usar o compilador de templates, pois ele dispensa uma etapa de build adicional.

Svelte O Svelte, por sua vez, não utiliza uma DOM virtual, e seu criador, Rich Harris, o descreve como uma "sobrecarga". Em vez de realizar diffing e reconciliação em tempo de execução, o Svelte emprega reatividade em tempo de compilação para analisar o markup e gerar código JavaScript otimizado que manipula o DOM diretamente, resultando em ganhos expressivos de desempenho.

Ver também

Shadow DOM

Categoria:Desenvolvimento web