LearnNewsExamplesServices
Frontmatter
number5408
titleNew major version: scoping (limiting) the vdom tree to own components
authortobiu
categoryIdeas
createdAtJun 3, 2024, 3:44 PM
updatedAtMar 4, 2025, 9:25 PM
closedClosed
closedAtMar 4, 2025, 9:25 PM
routingDispositionSchemaVersiondiscussion-routing-disposition.v1
routingDispositionterminal
routingDispositionReasongithub-closed
routingDispositionEvidencegithub:closed
contentTrust
projected
quarantined0
signals[]

New major version: scoping (limiting) the vdom tree to own components

IdeasClosed
tobiu
tobiuopened on Jun 3, 2024, 3:44 PM
We can start working on this one after the new product website & learning section went live.

Historically, we started to create a vdom tree which goes down into the deepest leaves (components). Sub-trees get passed as references into their owner components or containers. This approach is very fast & easy for rendering the entire main view (viewport) of an application, since we can directly pass the full tree to the vdom worker.

Once render() gets called on the main view, we get the vnode tree (current state) back from the vdom worker and delegate sub-trees to their owners. At this point, delta updates can start. This concept was already implemented before delta updates existed.

While the current approach works fine, it has 2 rather big downsides:

  1. Updates on containers which have many children are rather expensive, since we are passing big sub trees to the worker. To mitigate this, cls and style got a simplified updating logic to bypass the vdom engine (e.g. layout changes).
  2. Since all updates happen async, new updates can only start once the vnode tree of the last update got delegated to all child components. Meaning: an update can only start in case no parent or child components are in the middle of an update() call. While we do have many checks in place to ensure this, these checks are pretty complex and expensive.

The new scoped concept mostly affects containers. Instead of having the full vdom sub-tree, we should only inject references. Example:

vdom: {cn: [
    {id: 'myChildCmp1', isComponent: true, cls: [/*optional: add layout classes here*/]},
    {id: 'myChildCmp2', isComponent: true, cls: [/*optional: add layout classes here*/]}
]}

This way, containers can still take care of adding, removing & sorting child items and take care of layout related css classes.

What are the pros and cons of the new concept?

PRO:

  1. Updates will get faster, since we are sending way(!) smaller sub-trees to the vdom worker
  2. Update calls will only need to check if the same component is already updating. We can remove all parent & child status checks and remove the complex logic. This will also improve the stability for edge cases where a lot of updates happen in parallel.
  3. We can remove the custom cls & style based update mechanics, using the vdom worker as the single source of truth.

CONS:

  1. The initial rendering will get a little bit more complex: We need to use manager.Component to dynamically resolve reference items and create the full tree. To be clear: We only need to do this once.
  2. Since the vdom & vnode trees (current & next state) have to be in sync, we need to create a smart way to delegate the vnode tree to child components (it needs the same ids & scope).
  3. The util vdom & vnode helper methods will get a bit more expensive (e.g. in case you want to parse a vdom subtree to find items by id, flag / reference).
  4. The advanced concept of silently updating components and afterwards triggering an update() call on a parent container will no longer be possible.

SUMMARY: The scoped vdom tree should make it simpler for developers to use the neo framework. We have a better separation of concerns and less side effects developers need to think about. Having a focus on blazing fast dom updates => dynamic changes fits very well to the new concept. Of course we will do benchmarking once a PoC is fully functional.

tobiu
tobiucommented on Mar 4, 2025, 9:25 PM

resolved in v8.