VirtualDom implementation


#1

This is probably a question very specifically for Evan, but maybe someone else can answer.

I spent the weekend working on something I’m really proud of in Elm, and it involved creating a mockup version of the VirtualDom. This was surprisingly easy, and worked far better than I expected, which I think is a testament to the care and thought that has gone into the API.

But it raises a technical question about the VDom’s implementation for me: why is the diffing algorithm implemented so much in Javascript? Would diffing in Elm not be performant enough, or would it make for an ugly API, or is mutability required?

The reason I acted is the diffing algorithm seems to be tremendously good, and if it could be implemented in Elm, perhaps even abstract out so that it could be used on other tree-based scene graphs, that might have major implications that make it far easier to implement other APIs in the future, and make it easier to move Elm to other platforms or backends.

This is just a shower thoughts kind of thing, but I’d love to hear more from someone who knows the internals better.


#2

Not really answering your question, but I don’t know if you saw this post from a while back:

One issue I currently have with the VDOM implementation is that a VirtualDom.Node cannot be passed through a port. If it could, it would make server side rendering a lot simpler, as it would be possible to use a Platform.program and pass the rendered DOM through a port to serve up.


#3

I have seen that article, which is really great. It was while reading through its source code I decided to ask the question here.

I also came to it because the project I’m working on is around SSR and static site generation. I think I have a solution not involving send DOM nodes through a port, but not ready to publish yet (maybe next week, planning to show it off at elm NYC meetup next week).


#4

Cool, does that meetup have a dial in, would be great to listen in?


#5

It doesn’t, but unless someone comes up with a darn good reason that I can’t think of that this won’t work, I plan to publish something before the holidays.

If you for some reason have a project that needs it right away, send me a message and let me know. So far I’ve only tried the technique on a painfully simple two page app. I’m building out something more challenging to make sure it works on real applications.


#6

I can wait till you are ready to publish.

My approach is to put in a dummy function that takes a VirtualDom.node:

renderDom : VirtualDom.Node -> ()
renderDom _ = ()

Then after compilation, simply replace renderDom in the compiled JS with my own code.