whatwg / dom

DOM Standard
https://dom.spec.whatwg.org/
Other
1.57k stars 290 forks source link

Proposal for built-in method to synchronize elements with virtual DOM representation #1213

Open irony opened 1 year ago

irony commented 1 year ago

In the context of modern web development, many frameworks and libraries rely on the concept of a virtual DOM (VDOM) to manage and efficiently update the actual DOM of the web application. The ability to directly apply changes from a VDOM representation to the actual DOM in a standardized, efficient way could help in developing lighter and more performant libraries and applications.

To support this, I propose the addition of a new method to the Element interface. This method would take a VDOM representation (as an object or JSON structure) and efficiently apply changes to the element and its descendants to match the provided VDOM.

Each node in the VDOM could optionally include an id or key attribute. The browser would use these keys to determine which elements in the real DOM correspond to nodes in the VDOM. When synchronizing, if the method encounters a node in the VDOM that has the same key but is in a different position, it would move the corresponding element in the actual DOM to match the VDOM. If a node in the VDOM has a key that doesn’t exist in the actual DOM, the method would create a new element. If a node in the actual DOM has a key that doesn’t exist in the VDOM, the method would remove the corresponding element.

Potential method names could include syncWithVDOM, applyVDOM, updateFromVDOM, or renderFromVDOM. The best choice would depend on the specific semantics and behavior of the method.

For example, the usage could look like this:

let vdom = {
  tagName: 'div',
  attributes: { id: 'root' },
  children: [
    {
      tagName: 'h1',
      attributes: { key: 'heading' },
      children: ['Hello, world!']
    },
    {
      tagName: 'p',
      attributes: { key: 'paragraph' },
      children: ['Welcome to my app.']
    }
  ]
};

let element = document.querySelector('#root');
element.syncWithVDOM(vdom);

In this example, syncWithVDOM would ensure that the element matches the structure and content of the vdom object. If there were differences, it would make the minimum number of changes to the actual DOM to bring it into line with the vdom.

This feature would not replace the need for full-fledged frameworks like React or Vue, but it would provide a useful tool for developers building lightweight applications or libraries. It could also potentially increase the performance of DOM updates by leveraging browser internals and reducing reliance on JavaScript.

Please consider this feature for future improvements to the dom spec?

Thank you for your attention to this matter.

dead-claudia commented 6 days ago

As a virtual DOM library dev who's been in that field for almost a decade, I would like to advise some serious caution here, especially for frameworks and libraries other than React. (React's internal design is very different from most others'.)

Feeding literal trees is only half the battle. There's other child types common across virtually every virtual DOM implementation. To name a few:

Most of the code of a virtual DOM library isn't the immediate methods, but in trying to find ways to not update the DOM, making sure not to invoke components unnecessarily, and also just handling the other types of fragments. And in frameworks with the highest performance like Mithril.js, Vue, and Inferno, the very act of invoking DOM methods is itself very observable in profiles.

WebReflection commented 6 days ago

FWIWI this looks like a no-go to me ... to start with, we need a vDOM specification/standard to adhere ... secondly, the variety of template literals based solutions would beg to differ around the topic: "you don't need VDOM start with" would be their answer and mostly none of these libraries indeed use such pattern, as it duplicates the amount of RAM needed to retain trees live (on DOM) and trees live on the VDOM representation.

@dead-claudia also already made a very valid point: VDOM differs from project to project (library or framework) so I don't see how this could land as a standard method, where there's no sync even beyond the VDOM scene.

In short, and imho:

Until that, I am afraid this doesn't look like worth it ... if it is, I'll be happy to double the RAM on every library I have and have easier life diffing on my own things in JS literals and then propose changes to the browser as these come.