Hyperapp: Async rendering?

Created on 24 Apr 2018  路  11Comments  路  Source: jorgebucaran/hyperapp

Not sure if this one was on anyone's radar yet, but it's coming soon to React, so I figured I might as well ask.

It's my belief that if we decided to go async for our rendering in the future then apps built with Hyperapp best practices should still be able to work. Views should already be pure, and with the changes coming in 2.0 that will become even more so. Since lifecycle events are defined on the virtual DOM and not stateful components, they need not be run until all the DOM manipulations are committed, so side effects will only be run against a consistently-updated browser DOM.

The one area where I'm not sure if things would fall apart is with regards to interop. Could calling actions/dispatch from the outside world while async rendering was still happening cause bad side effects? It seems like with the right batching/queuing strategy any negative impacts of this could be mitigated.

As for whether implementing this feature would have any useful benefits or not, I'm unsure. 馃

Discussion

Most helpful comment

@noobiek I am working on it! 馃挭

All 11 comments

Beginner question:

Does async rendering mean that VDOM generation (running the view/component code) would be done in a web worker?

Thanks, :)

@russoturisto No, it doesn't mean that. It means that updating the DOM would be an async operation, instead of sync. If patching were async, we would be able to "call" actions inside the view and expect state updates not to destroy the work completed up to that point (but that now might always be the case even with async rendering). In V2 you there's no "calling actions" as we transition to purely functional views.

Understood, thank you for the explanation. :)

@jorgebucaran
Hi, are there any news on v2?

@noobiek I am working on it! 馃挭

I'm working on an experiment when I use lisp in JavaScript with hyperapp, I'm trying to write all the code in lisp but in my javascript lisp backquote return a promise instead of a value. So my app don't work because view is async. The value is resolved instantly but it's still a promise.

Do you plan of creating async rendering? I may as well update my lips to not return promise if values are not a promise, but was wondering if you plan to have it in 2.0?

@jcubic Using Lisp in JavaScript with Hyperapp? Nice. You were doing just fine until you said promises! You don't need promises to accomplish anything with Hyperapp. I can't see the connection. Pre-V1 used to support actions that return promises, but that was before I learned to walk. V1's render loop uses setTimeout and V2's render loop uses requestAnimationFrame. I briefly considered using Promise-based micro tasks, but it was problematic.

What async rendering refers to are asynchronous DOM updates, or the ability to update the DOM a bit, defer control back to the app, and resume updating the DOM at a later point in time. Never say never, but I'm "probably never" adding that to Hyperapp. We'll see. I'm skeptical of its real-world usefulness.

But what about time-slicing, suspense, high/low-priority updates, fibers? Optimizing for an impermissibly large DOM tree is a dead-end. Style calculations, and browser reflow, alone will make your application slow and utterly useless. That's your bottleneck. Fix that. Instead of optimizing for an absurdly large DOM tree, we optimize for real-world use cases.

Hyperapp's reconciliation/patch algorithm consists of a single immutable pass. Async rendering involves one or more passes and generating patch objects (or "fibers" in React land), whereas we apply all detected changes immediately.

Update your lisp experiment to not return a promise. 馃憢

The issue I was having is like this, you have view function and one the elements that render the view is asynchronous like function getTitle() that fetch title from server. The problem would be in my lisp, because If I use async function (function that return a promise) whole expression will be a promise so the view function in fact will also return a promise and whole rendering would fail.

Why not just allow promises to be returned from view function?

it's should be simple, just:

if (isPromise(result)) {
    return result.then(render);
} else {
    return render(result);
}

and updating rest of the code. In my lisp code I have few places like that (even recently refactored this to function unpromise) and because of that I can run (print (concat "title is " (getTitle))) but If I put this into view it will break.

Is there a workaround to make promise work with view function?

The view is not the right place for fetching data from the server, it's a pure function of state => VDOM.

Impure/async logic should happen inside FX that dispatch actions to update state which will then use your view to synchronously render the populated state.

@jcubic Is there a workaround to make promise work with view function?

No, there isn't, and that's a benefit. The problem is likely in your program design relying on promises.

Since you are using Lisp, and even wrote your own, I don't need to convince you that a pure function is preferable to one that is not. And there isn't much I can add to what @okwolf already said. Hyperapp views are pure functions receiving some state as input and producing a virtual DOM representation as output. No scoping, binding, this, async/await, promises, callbacks, observables, reactive expressions, reactive assignments, reactive declarations, subclassing, hooks, mutations, global state, or side effects.

@jorgebucaran @okwolf Thanks for explanation, will try to use FX then. When I was going to sleep last night I've realized that there are async actions in one of the examples (in version 1), and thought that this maybe the way to go with async code.

Thanks again and for this awesome micro framework.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jorgebucaran picture jorgebucaran  路  4Comments

ghost picture ghost  路  3Comments

jscriptcoder picture jscriptcoder  路  4Comments

icylace picture icylace  路  3Comments

dmitrykurmanov picture dmitrykurmanov  路  3Comments