Live data from Hacker News

Virtual DOM in Elm

elm-lang.org

71–80 of 117 posts

Re: Virtual DOM in Elm

#71
post #57

Earlier quoted context omitted.

I am currently writing an implementation of React in Scala.js. It's inspired by React and by the documentation of React, but I have not looked at the actual source code so far. You seem to be an implementor, so two questions that maybe spare me looking at the source code :-) 1. How do you batch updates? 2. I am currently using an algorithm for longest increasing subsequences for avoiding superfluous dom insertions of…

1. The boundaries are currently at event loop. Whenever an event comes in, we dispatch it to React and every time the user calls setState on the component, we mark it as dirty. At the end of that dispatch, we go from top to bottom and re-render elements. It's possible to change the batching boundaries via "Batching Strategies" but we haven't exposed/documented it properly yet. If you are interested, you can look at r…

Thanks a lot, very useful info. Yes, I know that because of state "diff" is really not diffing but synchronization of "blueprints" with actual "components". Still, after the update the order of the existing children of a node might have changed, and it is possible to devise a simple, not too costly (n log n, n is the number of children), and optimal strategy for rearranging the nodes.

Re: Virtual DOM in Elm

#72

Earlier quoted context omitted.

react.addons.update is a poor man's implementation of something like mori. I'm not going to go into details right now (also still early in research), but mori is way more efficient and provides a better API for working with this kind of stuff (`sort` return a new obj, etc).

Can we improve react.addons.update then? Mori is not syntax compatible with javascript datastructures, and needs to be marshalled to interop with javascript components. If you include marshalling overhead, mori is in the same ballpark as react.addons.update. http://jsperf.com/sprout-vs-mori/3

The reason why Mori scales better is because it implements arrays via a tree of 32-slot arrays. So unfortunately, you cannot use normal JavaScript data structures and have to re-implement all the array methods that know how to deal with this data structure.

React.addons.update uses normal JavaScript arrays. So it won't scale as well, but at least you get immutability.

Re: Virtual DOM in Elm

#73
post #66
post #42

Having done some benchmarks with TodoMVC before, I knew something was off about these results. They play to the strengths of the virtual dom approach by manipulating the benchmark via dom instead of what ever interface was implemented within each TodoMVC implementation. So I forked the benchmark and changed both the Backbone and Mercury implementations to work through their respective apis. Here it is: https://github…

In all javascript apps the part that is slow is the DOM, not the javascript interface. This benchmark was taken from the webkit source code then forked into http://vuejs.org/perf/ then forked to include mercury then forked again to include elm. Neither elm nor mercury came up with this benchmark and just added themself to it. What this benchmarks shows is that async rendering is really fast. Mercury, vue & elm all us…

There is interaction occurring with the DOM in both benchmarks.

The way that the Backbone TodoView is designed does not take into account the possibility of a user adding 100 items using the dom within a tight loop. Probably because such a use case is impossible outside of this type of benchmark. By doing so the Backbone implementation ends up performing a lot of unnecessary renders. Therefore as far as Backbone performance is concerned this benchmark is not indicative of any real world scenario.

Just to re-iterate; when you're loading a set of todos from your local storage to display when the user first opens the page, you would not populate the "new todo" input box and fake an enter event for each item that you want to add. Instead you would reset the Backbone.Collection with a list of your new todos (go through the interface). That's basically the change I made to the benchmark. Sorry if it wasn't clear.

Re: Virtual DOM in Elm

#74

Earlier quoted context omitted.

I am currently writing an implementation of React in Scala.js. It's inspired by React and by the documentation of React, but I have not looked at the actual source code so far. You seem to be an implementor, so two questions that maybe spare me looking at the source code :-) 1. How do you batch updates? 2. I am currently using an algorithm for longest increasing subsequences for avoiding superfluous dom insertions of…

1. We buffer calls to setState() and apply them all at once (they don't trigger re-renders) and mark those components as dirty. Then we sort by the depth in the hierarchy and reconcile them. Reconciling removes the dirty bit, so if we come across a node not marked as dirty we don't reconcile (since it was reconciled by one of its parents). 2. I don't think we spend a lot of time trying to make this super optimal, but…

Thanks a lot! I grepped it but I cannot really figure out the strategy from the source code. Probably you are doing something similar to what I am doing.

Re: Virtual DOM in Elm

#75
post #57

Earlier quoted context omitted.

I am currently writing an implementation of React in Scala.js. It's inspired by React and by the documentation of React, but I have not looked at the actual source code so far. You seem to be an implementor, so two questions that maybe spare me looking at the source code :-) 1. How do you batch updates? 2. I am currently using an algorithm for longest increasing subsequences for avoiding superfluous dom insertions of…

1. The boundaries are currently at event loop. Whenever an event comes in, we dispatch it to React and every time the user calls setState on the component, we mark it as dirty. At the end of that dispatch, we go from top to bottom and re-render elements. It's possible to change the batching boundaries via "Batching Strategies" but we haven't exposed/documented it properly yet. If you are interested, you can look at r…

If you think you can make it better in React, pull requests are more than welcome. For example, we didn't have batching when we open sourced React and it was written by the community :)

Re: Virtual DOM in Elm

#76

Earlier quoted context omitted.

Can we improve react.addons.update then? Mori is not syntax compatible with javascript datastructures, and needs to be marshalled to interop with javascript components. If you include marshalling overhead, mori is in the same ballpark as react.addons.update. http://jsperf.com/sprout-vs-mori/3

That's the thing I love about React though; you don't have to marshal if you embrace mori wholesale. I can render components based on these data structures and never have to "reify" them into real JS data structures. That said, I'm probably being overly optimistic and I'm just starting to research it. I don't quite like how addons.update feels like a bandaid, but maybe it is good enough. Haven't done enough research…

I've done some research too - check out this implementation of cursors, it enables drop-in O(1) shouldComponentUpdate (like Om) and is compatible with rAF batching (like Om). We explored Mori for a bit too and ended up deciding Mori wasn't worth it. (Our app was big enough that we experienced pretty brutal performance without shouldComponentUpdate. Now our bottleneck is methods like Array.prototype.map over large lists in render, which Mori can't help with - we have to restructure our state away from lists and into trees to better take advantage of shouldComponentUpdate)

https://github.com/dustingetz/react-cursor/blob/master/examp... https://github.com/dustingetz/react-cursor/blob/master/js/Cu...

(It is backed by react.addons.update, it provides a mechanism like mori.assoc_in for immutable subtree updates, and it preserves reference equality for equivalent cursors (value/onChange tuples))

(Cursors are also not vulnerable to issue#122 https://github.com/facebook/react/issues/122)

Re: Virtual DOM in Elm

#77
post #63

Earlier quoted context omitted.

Because the underlying DOM is essentially untyped. This is a low-level adaptor library. One could easily build a more strictly typed wrapper on top.

Let me rephrase the question: why haven't they already?

Why haven't you already?

They're literally announcing the untyped base library layer and the post specifically calls out the desire to build higher level abstractions. Elm is moving incredibly fast, so your question is totally unreasonable.

Re: Virtual DOM in Elm

#78
post #72

Earlier quoted context omitted.

Can we improve react.addons.update then? Mori is not syntax compatible with javascript datastructures, and needs to be marshalled to interop with javascript components. If you include marshalling overhead, mori is in the same ballpark as react.addons.update. http://jsperf.com/sprout-vs-mori/3

The reason why Mori scales better is because it implements arrays via a tree of 32-slot arrays. So unfortunately, you cannot use normal JavaScript data structures and have to re-implement all the array methods that know how to deal with this data structure. React.addons.update uses normal JavaScript arrays. So it won't scale as well, but at least you get immutability.

If your react state contains large lists, I think React's render() is going to be the bottleneck, not javascript arrays. That's why react state needs to be structured in a tree, so you can implement shouldComponentUpdate and get O(log n) renders. I wrote more in reply to jlongster.

Re: Virtual DOM in Elm

#79
post #59

Earlier quoted context omitted.

While each use case is different, I'd like to clarify a few things in my OP. DOM reuse is not the same thing moving a DOM subtree to a different place. DOM reuse is e.g. getting an already-rendered table row, binding a new value to it, and modifying only the DOM properties in the complex DOM structure that actually did change. E.g. you modify only an Element.text deep in the first column, and a few other values in th…

You get all of this for free with React. DOM node reuse is perhaps the central theme of React so it's odd that you bring this up as a criticism (see https://www.youtube.com/watch?v=1OeXsL5mr4g ) Calculating the virtual DOM does come with some processing and GC overhead, yes. But any system that tracks changes for you (data binding) comes with overhead and React makes the right set of tradeoffs for real apps (since it…

On the DOM reuse: could you help me out? I'm sure if I watch all the videos I may be able to figure it out, but I'd be interested in a trivial example. Let's assume I have the following structure (additional cells and rows are omitted for cleaner display, please assume we have 1000 rows and 20 cols):

    
      
        
          Value.
        
      
    
I want to reach the following:

    
      
        
          Value B.
        
      
    
What do I need to do in React that on updating the underlying data, only the innermost Element's class attribute and innerText would change, and the rest of the DOM will be kept intact?

Re: Virtual DOM in Elm

#80
post #79

Earlier quoted context omitted.

You get all of this for free with React. DOM node reuse is perhaps the central theme of React so it's odd that you bring this up as a criticism (see https://www.youtube.com/watch?v=1OeXsL5mr4g ) Calculating the virtual DOM does come with some processing and GC overhead, yes. But any system that tracks changes for you (data binding) comes with overhead and React makes the right set of tradeoffs for real apps (since it…

On the DOM reuse: could you help me out? I'm sure if I watch all the videos I may be able to figure it out, but I'd be interested in a trivial example. Let's assume I have the following structure (additional cells and rows are omitted for cleaner display, please assume we have 1000 rows and 20 cols): Value. I want to reach the following: Value B. What do I need to do in React that on updating the underlying data, onl…

Can't respond to you on react (though my impression is that the entire point of virtual DOM diffing is to do exactly what you're after), but can you justify in some way your HTML markup using and instead of and ?
Post reply on HN