
Reactive MVC and the Virtual DOM - jessaustin
http://futurice.com/blog/reactive-mvc-and-the-virtual-dom
======
avodonosov
> The gist is to frequently re-render a complete and lightweight
> representation of the DOM, then apply a difference filter to detect the
> minimum changes that need to be made to the DOM. A similar technique has
> existed in game development long before React: re-render the game screen in
> every game loop, but only update the minimum portion of the screen which
> changed compared to the previously rendered screen.

Practically every desktop UI works that way (Windows API, X Windows, Java UI
libs). It's funny to see how web programming in 2015 slowly reinvents the
wheels known since 1970s.

~~~
thedz
The browser that is rendering the DOM also, ultimately, works that way, with
various portions of the browser screen redrawing while others remain static.

So it's kinda funny that the modern state of web dev is adding another layer
of that same approach on top of layers of that approach.

~~~
malkia
The missing part in the DOM is:

    
    
      freeze()
    
      doLotsOfUpdates()
    
      thaw()
    
    

So one would have to reinvent this. Kind of reminds of propeties in some
languages, runtimes and their UI's:

    
    
      someForm.setWidth(500); // And it's updated right away on the screen, instead of being deferred, or put in some freeze()/thaw() mode. (disableUpdates() / enabledUpdates()).

~~~
avodonosov
Our scripts are executed in a freeze mode.

When we modify DOM it becomes "dirty", and after our script finishes,
reflow/re-render happens. But also, if our script queries DOM properties, like
elem.clientHeight, DOM may need to perform the calculations in order to return
us correct values, reflecting all the recent property changes. For example, if
we access element.clientHeight browser may need to calculate re-flow (I
recently encountered very slow clientHeight calculation by FireFox).

So, if we only modify DOM properties, all the re-rendering is deferred till
the end of script.

Google about "DOM reflow"

------
guscost
> Flux attempts to be reactive by making Stores listen to Dispatcher events,
> and Controller-Views listen to Store events. However, the centralized
> Dispatcher is imperatively controlled by Actions, rather than taking the
> responsibility to observe Actions.

This can definitely be disorienting since by default you use imperative APIs
to create the actions, and then switch to working with events and subscribers
from the dispatcher up until the re-render. I've not had too much difficulty
with this, at least after some initial confusion.

> Flux dictates that inter-model dependency should live in the Dispatcher, but
> in MVI, those dependencies are defined inside each Model.

Maybe this should be edited. Flux stores are the analog of models, and each
store can define which other stores have to finish updating before it responds
to a given action (in that big case statement where it registers with the
dispatcher).

The arguments for RxJS, testable view functions, and avoiding internal
component state are important. The dispatcher being a singleton doesn't seem
to affect much in practice, since that code is never really touched. Looks
like performance could be better with virtual-dom but I'd be interested to see
the different optimization strategies for each architecture and how they
affect performance. Some of my own notes about optimizing React/Flux are here
if you're curious: [http://guscost.com/2015/05/27/react-js-and-flux-ideas-for-
pr...](http://guscost.com/2015/05/27/react-js-and-flux-ideas-for-practical-
applications/)

Also I think that reusable components is a really nice feature and I would
encourage you to continue working on including this functionality. All in all
a very nice piece, thanks for writing it up.

------
rattray
I like the idea of moving that arrow the way he does.

Everything else was just less convincing. The real power of React is
composable components that are easy to think about. I don't think the author
really "got" this; if he was building "complex state machines ... and [mixing]
multiple concerns in one component", he was just doing it wrong.

I also don't love the idea of stores depending on each other. In my
experience, it leads to hard-to-maintain tangled interdependencies, especially
on the frontend. I actually tried to use Bacon.js as a Flux replacement
because of the reactive philosophy (this article was a source of inspiration),
and while it was nice, the purported benefits of Rx fell flat and store
interdepencies remained a problem.

Now, I use NuclearJS [0] to avoid store interdependency altogether. It's
actually what I was trying to build with Reactive programming, but done
better.

[0] [https://github.com/optimizely/nuclear-
js](https://github.com/optimizely/nuclear-js)

~~~
mrcwinn
Completely agree. Looking at his eventual realization of these ideas,
Cycle.js, it's just a complete mess in terms of declarative, easy to
understand components. The beauty of React, beyond its simple lifecycle API
and virtual DOM, is that you can glance at a component and very quickly reason
what it does and how it works. I can't say the same for anything that came out
of this article.

There's a tendency in JavaScript development especially to overthink, over-
engineer, and over-abstract. We're still in the middle of the woods with
JavaScript application development. I hope we get out soon!

------
raffomania
Interestingly, the sliders in the MVI example seem to react way more slowly...

~~~
meowface
Same for me.

------
BinaryIdiot
Good write-up and similar to some of my findings. In fact I like the event
emitting / messaging pattern so much I wrote a little library called msngr.js
([https://github.com/KrisSiegel/msngr.js](https://github.com/KrisSiegel/msngr.js))
to do the same type of thing.

I'm not entirely convinced of the separate "renderer" or really the act of
updating a virtual dom but I do like the model-view-intent. What I've done is
something pretty similar though typically I combine the model and the view in
all cases but the main application itself. Basically the breakdown is like
this:

Application controller - initializes application components / authorization /
anything necessary for startup

Web components - Either through webcomponents.org polyfills or polymer these
are the individual components that make up the user interface of the web
application. Each web component is entirely responsible for its interaction
with the user. It subscribes to messages when it should take in updates and it
emits the data the user inputs.

Application libraries - Handles the other end of messaging; has zero
interaction with anything within the DOM. Subscribes to data that gets emitted
from the web components and emits data that the web components need to display
to the user.

I try to keep things as basic as possible. I'm still experimenting and working
on an example web application using msngr.js that I can actually release as
open source but I am a fan of this type of pattern. The best part of this is I
can do full unit testing on the application libraries with zero DOM and the
web component side of things can be fully tested with mocked results.

------
SeeThruHead
Looks to be the same idea as Cycle.

[https://github.com/staltz/cycle](https://github.com/staltz/cycle)

~~~
dustinswan
He wrote Cycle

