From: Alain Frisch <alain.frisch@lexifi.com>
To: Yaron Minsky <yminsky@janestreet.com>
Cc: ocsigen@inria.fr, OCaml Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] Announce: ocaml-vdom (pre-release)
Date: Thu, 1 Dec 2016 10:32:15 +0100 [thread overview]
Message-ID: <0f6d69bb-a458-5876-3c60-a29befab02d1@lexifi.com> (raw)
In-Reply-To: <CACLX4jQRBVu1mcaqpmiHu6_2s_Bpk7L7gzSwbiU+qLscDSnoLg@mail.gmail.com>
Hi Yaron,
On 30/11/2016 20:22, Yaron Minsky wrote:
> I'm curious if you have any story for making the recomputation of the
> virtual-dom itself more efficient.
> ...
> That said, for small UIs, this kind of incrementality is less
> important, so whether this is worth doing may depend on your
> applications.
Our story w.r.t. updating the vdom itself is the same as Elm, I believe:
1. In the vast majority of cases, the mapping from the "state" to the
vdom is very quick and it is ok to recompute the full vdom on every
state change.
An argument often made in the vdom space is that a UI usable by
human-beings cannot possibly have a very big DOM (moreover, even recent
browsers such as the latest Edge or Firefox struggle with tables
starting at a few thousands rows), and that computing the full vdom
"cannot be that costly". I don't want to enter such discussion here,
but in our own use cases, we indeed try to avoid "overly big UIs" and we
don't have strong performance requirements such as continuous streams of
updates pushed by the server; if it takes 10ms to react on a user UI
event, it is perfectly fine for our case. My intuition is that most
applications would be a similar situation, but I appreciate that you
have very different kinds of UIs and performance constraints that
require a more incremental approach.
2. The library provides:
val memo: ?key:string -> ('a -> 'msg vdom) -> 'a -> 'msg vdom
(** Apply the function to generate a VDOM tree only if the function
or its argument have changed (physically) from the previous
synchronization. *)
(similar to Elm's Lazy:
http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Lazy )
This is typically used when embedding the view of a "sub-component"
derived from only part of the our current state. If we can ensure this
sub-part remains the same, the previous vdom (at the same "site") is
reused, which skips both the vdom generation and the vdom diffing.
Typically, the generation function would be a toplevel declaration (so
it will always be the same, physically) and we arrange to avoid touching
the part of the global state on which it depends.
Of course, it is also possible to use any other mechanism (such a
memoization table) to reuse previously computed vdoms.
> Another thought: you might want to consider the design we used for our
> wrapper on Matt Esch's virtual-dom library. In particular, in our
> design we don't need a type-parameter for vdom nodes determining the
> type of a message, and we don't need the corresponding map
> functions. Instead, we use open types and a registration and dispatch
> mechanism for values thus injected.
Thanks for the hint.
Do you have pointers to code examples using the "inject" function? It
seems to me that you will need to apply to it produce any "message" in
the view function.
In our library, you can write directly:
input "+" ~a:[value "+"; type_button; onclick `Plus]
With the "inject" approach, do you need to write it like:
input "+" ~a:[value "+"; type_button; onclick (inject `Plus)]
?
If so, this does not seem strictly lighter than using the "map" function
occasionally. Moreover this seems to open the door to possible problems
if a vdom fragment producing some kinds of messages is injected in a
"host application" that cannot process these messages. It also means
that one needs to take the identity of the "inject" function itself into
account in order to memoize vdom-generation functions.
Basically, we need "map" on "component boundaries", and even not always,
since components can take ad hoc injection functions to wrap their
messages into their "host" own message type (as the SelectionList
example in
https://github.com/LexiFi/ocaml-vdom/blob/master/examples/vdom_ui.mli ).
The library does use extensible types (with a registration/dispatch
mechanism) in two other places, though:
- "Commands" (encapsulation of side-effectul operations). The set of
"command constructors" is small and has a global nature (e.g. "AJAX
query", "timer", etc), while the type of "messages" is specific to each
application and component.
- "Custom nodes" in the VDOM which allow plugging "native" components
(again, the set of such possible components is more "fixed" than messages).
Alain
next prev parent reply other threads:[~2016-12-01 9:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-30 16:52 Alain Frisch
2016-11-30 19:22 ` Yaron Minsky
2016-12-01 9:32 ` Alain Frisch [this message]
2016-12-01 22:18 ` Yaron Minsky
2016-11-30 22:46 ` Martin DeMello
2016-12-01 9:56 ` Alain Frisch
[not found] ` <CAG+nEjzO1qFfxHSMqueiKcTJyJYnREmvXhzGR7H+noBmV2oUKw@mail.gmail.com>
2016-12-02 13:41 ` Alain Frisch
2016-12-02 16:59 ` Vincent Balat
2016-12-02 18:18 ` Alain Frisch
2016-12-02 22:31 ` Yaron Minsky
2016-12-10 13:34 ` SP
[not found] ` <5db7c03d-bec8-8285-b458-82e681842dbb@zoho.com>
2016-12-05 15:55 ` Ashish Agarwal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0f6d69bb-a458-5876-3c60-a29befab02d1@lexifi.com \
--to=alain.frisch@lexifi.com \
--cc=caml-list@inria.fr \
--cc=ocsigen@inria.fr \
--cc=yminsky@janestreet.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox