caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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

  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;
as well as URLs for NNTP newsgroup(s).