6 ms·
> I feel like this is one of those cases where someone rejects currently existing tools, but then goes on to throw out the baby w/ the bath water when trying to
by carsongross 11y ago
> I feel like this is one of those cases where someone rejects currently existing tools, but then goes on to throw out the baby w/ the bath water when trying to come up w/ an alternative.
Humorously, this is exactly what the current set of client side MVC libraries did.
- lhorie 11y agoNo offense, but I think it's disingenous to compare the SPA movement with a guy with vague graphs that look like they suggest going back to what people used to do 5-10 years ago. The SPA movement "threw out" the notion of ajaxing HTML snippets in favor of ajaxing structured data for many reasons: better separation of concerns, better asset cacheability, better defaults against XSS, better infrastructure for multi-client architectures, the list goes on. I'd argue that security w/ data endpoints is far easier to audit and reason about than the old school RPC-style send-me-html-when-I-do-X server interfaces.
- EGreg 11y agoAJAXing data is great (It should be AJAJ btw :) But when do you update the view? Angular dirty-checks the model on each $digest cycle. React dirty-checks the view. Why not simply require the component to call a function to indicate it's changed a couple variables in its state? Simply keep references to the DOM elements in your component and update them. It's much faster and gives you more control, and a programmer who forgets to write the function call will realize it as soon as they don't see the update. The IDE or linter can even have a static analyzer that flags a missing call to the function. I think that a lot of times these attempts at convenience (such as Angular's two way binding, or the virtual DOM) just throw more layers of complexity and slow things down from a relatively simple straightforward approach, while providing little other than saving keystrokes.
- lhorie 11y ago> Why not simply require the component to call a function to indicate it's changed a couple variables in its state This is actually roughly what knockout and ember (pre-glimmer) do. They are known as KVO (key-value observer) systems and have implementation challenges of their own: knowing when to batch operations, dealing w/ computed properties and rx glitches (in reactive systems, a "glitch" is the name given to temporary inconsistencies that occur between stable states), and added complexity in terms of requiring the model layer to be observable-based (as opposed to POJOs in Angular/React/friends). Also, high quality KVO systems are far more difficult to implement. To my knowledge, Vue is currently the fastest KVO-based javascript library in existence and in order to support its POJO-like model API, it's significantly larger than Snabbdom (which is one of the fastest vdom implementations currently, despite clocking at a mere 200-300 LOC) AFAIK, most of the challenges faced by KVO system have not been as extensively explored (at least by the javascript community) as virtual dom algorithm optimizations have, so currently I believe high quality virtual dom libraries are likely to perform better at various real life scenarios than current state-of-art KVO systems.
- EGreg 11y agoRight. But why not just make the app developer explicitly specify that some variables in the state have changed, and let the developer and requestAnmationFrame do the batching? After all, they are the best positioned to know when a batched update has been done.
- lhorie 11y agoLetting the developer tell the engine when to batch is actually not the hard part. React works exactly like that, for example. Mithril defaults to most-common-scenario call profile, but mostly as a matter of convenience, not because there's anything inherently difficult about exposing that flexibility to the developer. The pain point that templating engines address is automating the process of figuring out what DOM changes are caused by what state changes. In order to do that, you have to either dirty check the state tree (as Angular 1 does), dirty check the template tree (as React/Mithril/vdom does), or have an observable state tree (as Knockout does). If the templating engine defers its responsibility to the developer, then if, for example, you do a `dataList.pop()`, you are responsible for writing out the code to remove the last item in a DOMNodeList, or updating some count label, or whatever else the view may be doing. This works ok in a small app, but it tends to become hard to maintain as a codebase grows in size (due to requirement changes or whatever).
- EGreg 11y agoIn 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 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?
- joesb 11y ago> But when do yo update the view? Angular dirty-checks the model on each $digest cycle. React dirty-checks the view. The answer is in that statements. Angular and React is not you. > Simply keep references to the DOM elements in your component and (you) update them. It's much faster and gives you more control... The point of React and Angular is that you don't have to think about updating the DOM.
- EGreg 11y agoSo they run into the typical problem of handling the "general case" in their own special way, and leaving you out in the cold for the other cases. Someone made a chess move? Someone queued a new song? Someone wrote a new chat message?