Mithril.js: [rewrite] Timing

Created on 7 Sep 2016  路  5Comments  路  Source: MithrilJS/mithril.js

I think that the way time (sync vs async behavior, and the order of operations) is handled in Mithril could be tightened a bit and wanted to spark a discussion on the topic. Here's what I propose:

m.redraw()

As suggested in #1166, I think that having

  • redraw() being always deferred + throttled and
  • redraw(true) or redraw.sync() being always synchronous, cancelling pending async redraws would be ideal. forced sync redraws are out as of 713c25c9c0490a7f50368209148737bf76647dd7

Keeping the current hierarchy between root.redraw and m.redraw seems good.

For simplicity, the framework should use defered drawing everywhere (except m.render obviously), and let the user opt in to synchronous behaviour with m.redraw(true) if needed. Otherwise the user has to keep tabs on what is sync/async, and by how much...

m.mount

Currently fully synchronous. Should redraw asynchronously.
Currently re-mounting an existing root with another component pushes it at the end of the redraw() list. It may be nice to preserve the current place instead unless the node is cleared withmount(root, null)(mimicking what JS does for theObject.keys` order).

Core Router

The ideal situation would be to make it work as synchronously as possible (the only thing that really needs debounceAsync is history.back() with onpopstate, to make it work like onhashchange which is debounced and async.).

Route.set can be made synchronous by disabling onhashchage while setting document.location and calling a synchronous resolve manually.

Router API

These are consequences of the previous points:

| Operation | Current | #1291 | Ideal (if we must support ie9) |
| --- | --- | --- | --- |
| route() from a valid URL | async | sync | sync resolution (unless delayed in resolve), async redraw |
| route() from an invalid URL | async x 2 | debounced async | sync resolution (unless delayed in resolve), async redraw |
| route.set() to valid URL | async | debounced async | sync resolution (unless delayed in resolve), async redraw |
| route.set() to invalid URL | async x 2 | debounced async x 2 | sync resolution (unless delayed in resolve), async redraw |
| history.back() ie9/onhashchange | debounced async x 2 | debounced async | debounced async resolution, async redraw |
| history.back() onpopstate | async | debounced async | debounced async resolution, async redraw |

"debounced async" means that several sync calls are throttled to a single deferred action. "x 2" means that there are two nested timeouts.

Most helpful comment

:+1: for redraw.sync() instead of redraw(true), since the latter isn't clear and requires looking up docs to understand what it's doing.

All 5 comments

I forgot to expand on the reason why I think having redraws deferred by default is better. It allows to call redraw without having to worry about double redraws. For example, you could do

m.request(...).map(_ => m.route.set("/foo"))

More generally, if foo() and bar() are operations that both trigger a redraw, you can then call foo();bar() and get a single redraw. You don't have to create non-redrawing versions of each if you want to combine them. You can also sprinkle redraws() in your code liberally without having to fear a double redraw (or having to use setTimeout if you want to make sure a redraw() occurs asynchronoulsy.

I think that point has already been made in the issues somewhere, but I can't remember where.

:+1: for redraw.sync() instead of redraw(true), since the latter isn't clear and requires looking up docs to understand what it's doing.

For reference, here are the two issues with the previous discussion: #1100 (starting from this comment) and #1166.

And yes, I'm hugely in favor of doing async redraws by default (IMHO sync redraws shouldn't even be an option except through mithril/render directly).

m.redraw(true) is gone... I won't mourn it.

@lhorie what's the use case for the unpredictable timing of m.redraw()?

Closing, since this issue/PR has not been updated in over a month, and typically, issues inactive for that long do not usually produce any action. If you feel something in Mithril needs added or changed, please file a new issue/PR.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hadihammurabi picture hadihammurabi  路  4Comments

raykyri picture raykyri  路  4Comments

andraaspar picture andraaspar  路  4Comments

dhinesh03 picture dhinesh03  路  4Comments

josephys picture josephys  路  4Comments