Hacker News new | ask | show | jobs
by atlassubbed 2765 days ago
Imba claims to use an "imperative, memoized DOM" as opposed to a VDOM. Apparently it looks like they still use a VDOM (i.e. a wrapper around the DOM). The difference is that, at compile time, they attempt to unmix the dynamic parts of a template from the static parts, then they memoize the static parts for you automatically.

Sure, there are issues with existing VDOM implementations that do not do these compile-time optimizations:

  1. Returning new JSX elements from every render
  2. Building key indexes for every subdiff
The first issue can be solved with application-specified memoization in render. The second issue is pretty hard to avoid if you want to avoid matching elements based on indexes (naive subdiffs). Implicit and explicit keys are there for a reason, namely that moving elements is assumed to be a much less expensive operation than unmounting and re-mounting them. The O(N) trash memory overhead per subdiff incurred due to key indexes is justified, in my opinion. If using an algorithm like LCS, you'll incur more time/space cost, but you will even further minimize the edit path.

If I'm not mistaken, Imba would have to use something similar to key indexes if they want to avoid unnecessary unmounting and re-mounting for templates which are composed of large dynamic lists.

I'm not sold on Imba's value proposition. The value proposition is compile-time memoization for static elements, so you avoid re-creating those templates during renders. That's great and all, but how much of SPA webapps are purely static elements? For example, consider the the following JSX template:

  <ul>
    {this.state.bigList.map(i => <li>${i}</li>)}
  </ul>
I don't think Imba would perform much better than these other libraries for templates which are 99% dynamic (like this one), and so the dominating term here is the subdiff term, where you will end up either:

  1. Creating at least O(N) trash memory (e.g. key indexes)
  2. Doing unnecessary mounts and unmounts
1 comments

We do recommend using keyed elements (indexing using <tag@{mykey}> syntax) for large lists. It includes automatic pruning of cached unmounted elements etc if you reach a certain threshold of unique memoized nodes within a list over time).

It performs a lot better for a platform like scrimba at least - which is pretty dynamic.

I just hope other frameworks will adopt our approach, because it really is a huge step forward compared to most of what is out there today.

I don't think any of my concerns were addressed. If I index a <p@key1/> and its position changes in the child list, will the diff move the node (e.g. insertBefore) as opposed to unmounting/remounting it? Also, have you tested the performance of a Fisher-Yates shuffle on a list like [<p@key_i>]? I'm curious if that is faster than React. There are some cases where you'd want many list elements moving around.