In our framework, we just give a standard way for the developers to refresh tools and make incremental updates:

http://qbix.com/platform/guide/tools#dom

Remember, tools are reusable and the tool's developer is the one who has to write that code. The app developer just plops the tool on a page and it renders itself.

Most tools don't need 60fps efficiency for animations. they would implement a simple .refresh() method (similar to React's render method, except without the virtual DOM). When the tool is first activated, it typically renders any HTML it needs to inside this method, unless the HTML was already there (because eg it was rendered server-side). It typically renders a template with some fields fromthe state, just like in Ember.

Right after this, the tool usually just stores references to elements it wants to update. For example,

tool.$foo = tool.$(".someNode");

And then when it comes time to update, you just do:

someTool.state.x = 5;
someTool.state.y = 8;
someTool.state.z = "moo";
someTool.stateChanged("x", "y", "z");

And the tool's constructor method would have done this:

this.onStateChanged("x","y")
.set(function (oldValues) {
this.$foo.html(
this.state.x + this.state.y
);
});

This event occurs whenever either x or y was reported as changed. Our framework would make sure these onStateChanged events are triggered at most once per animation frame.

In your example, I'd signal that some array changed, and the tool would figure out what changed via dirty checking. But why do that crap? Why dirty-check at all? In our framework, we have streams and messages posted to the streams which are supposed to say what changed. A move was made in a chess game. A person wrote a chat messge. These things are updates, which are hard to represent in Angular and React as mere maps from plain data to the DOM.

What's wrong with that? Any tool developer can add event listeners for when something changes, and do whatever update thy have to do. The app developer just updates a tool's state and it just works. If you need 60fps or just want to render 1,000 constantly updating tools on a page (BAD IDEA) then you can do it.

I guess I should have said that the rest of our framework uses the same concepts. Instead of syncing data like Firebase or Parse, we treat data as streams onto which one or more collaborating users post messages. We take care of making sure the order of the messages is the same everywhere, and we take care of a ton more things such as pushing realtime updates, managing subscriptions, access control etc. All you have to do is implement the visual change when the server says a chess move has been made, etc.

We even have a convention for "optimistic" changes that assume that your POST succeeded by simulating messages that should have come in. Once in a while, the assumption is violated, eg if another user posts another message in the meantime, or the server becomes unreachable. Then we .refresh() the stream to its last confirmed state and all tools automatically refresh also because they have event listeners on that Q.Stream object's onRefresh event. Then your tool may want to retry the pending actions with OT, ask the user, or whatever. And so forth.

Have you seen any framework with this straightforward model?