mozilla / reflex

Functional reactive UI library
MIT License
367 stars 20 forks source link

Performance feedback #46

Closed Gozala closed 7 years ago

Gozala commented 8 years ago

@tschneidereit Any feedback of possible bottlenecks would be great.

application.js

I would start reading from this file. The start function is what wires everything up. beginner is just a functions that transform trivial app configuration the the one that start expects.

Configuration passed to start is expected to contain flags (which some data that is just forwarded to) init function, update and view functions.

One semi-confusing thing is that functions used to build virtual-dom tree (see dom.js) provide implementations of node, text and thunk that either just delegate to same named functions on mysterious driver or just return boxes that do that on .force(). This is to facilitate swappable drivers for rendering. The way it works is that after update returned a [model, fx] new view is created as root(view, model, address) then if driver is plugged it will update it's internal state with that VirtualRoot instance & schedule an animation frame & once animation frame is triggered VirtualRoot instances renderWith is invoked with actual virtual-dom implementation of that driver. So at the end of the day node, text and thunk just delegate to driver.node, driver.text and driver.thunk that does rendering. Only exception is if fragment of the virtual-tree is created outside of the view function (for example reusable static chunk is defined outside of view function) in such case LazyNode and friends are created, which are then .force()-ed as they get included inside actual virtual-dom tree.

signal.js

Provides simplistic implementation of FRP signals, if not familiar with FRP think of it as streams. Above mentioned start returns view, task and model signals. Drivers are plugged by subscribing to a signal. So in case of renderer, we subscribe to the view signal and every time we receive new value we schedule animation frame and update internal ref of what needs to be rendered. task signal similarly is a signal for requested effects (that init and update return). That also works with a driver, which performs those tasks and feeds results via actions into address.

task.js

Provides API very similar to Promise, primary difference is that it that it's not an eventual result of a computation but rather an eventual computation that driver can execute if so choses. Primary purpose of tasks is to do IO like XHR or even things like mutate DOM.

effects.js

This is kind of facility do to wiring / routing of tasks. When I mentioned that init / update return [model, fx] the fx part was instance of Effects. Effects just allow you to tag results of tasks they wrap, or batch several of them together. Or just imply no effects via Effects.none.

Gozala commented 8 years ago

@tschneidereit does it still makes sense to keep this one open ?