{"action":"created","issue":{"url":"https://api.github.com/repos/mozilla/reflex/issues/46","repository_url":"https://api.github.com/repos/mozilla/reflex","labels_url":"https://api.github.com/repos/mozilla/reflex/issues/46/labels{/name}","comments_url":"https://api.github.com/repos/mozilla/reflex/issues/46/comments","events_url":"https://api.github.com/repos/mozilla/reflex/issues/46/events","html_url":"https://github.com/mozilla/reflex/pull/46","id":148188785,"number":46,"title":"Performance feedback","user":{"login":"Gozala","id":21236,"avatar_url":"https://avatars.githubusercontent.com/u/21236?v=3","gravatar_id":"","url":"https://api.github.com/users/Gozala","html_url":"https://github.com/Gozala","followers_url":"https://api.github.com/users/Gozala/followers","following_url":"https://api.github.com/users/Gozala/following{/other_user}","gists_url":"https://api.github.com/users/Gozala/gists{/gist_id}","starred_url":"https://api.github.com/users/Gozala/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gozala/subscriptions","organizations_url":"https://api.github.com/users/Gozala/orgs","repos_url":"https://api.github.com/users/Gozala/repos","events_url":"https://api.github.com/users/Gozala/events{/privacy}","received_events_url":"https://api.github.com/users/Gozala/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"tschneidereit","id":56359,"avatar_url":"https://avatars.githubusercontent.com/u/56359?v=3","gravatar_id":"","url":"https://api.github.com/users/tschneidereit","html_url":"https://github.com/tschneidereit","followers_url":"https://api.github.com/users/tschneidereit/followers","following_url":"https://api.github.com/users/tschneidereit/following{/other_user}","gists_url":"https://api.github.com/users/tschneidereit/gists{/gist_id}","starred_url":"https://api.github.com/users/tschneidereit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tschneidereit/subscriptions","organizations_url":"https://api.github.com/users/tschneidereit/orgs","repos_url":"https://api.github.com/users/tschneidereit/repos","events_url":"https://api.github.com/users/tschneidereit/events{/privacy}","received_events_url":"https://api.github.com/users/tschneidereit/received_events","type":"User","site_admin":false},"milestone":null,"comments":1,"created_at":"2016-04-13T21:32:59Z","updated_at":"2016-06-20T18:34:09Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/mozilla/reflex/pulls/46","html_url":"https://github.com/mozilla/reflex/pull/46","diff_url":"https://github.com/mozilla/reflex/pull/46.diff","patch_url":"https://github.com/mozilla/reflex/pull/46.patch"},"body":"@tschneidereit Any feedback of possible bottlenecks would be great.\r\n\r\n### [`application.js`](https://github.com/Gozala/reflex/pull/46/files#diff-a418f1fe004a566b539ca636b9c906f1)\r\n\r\nI 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.\r\n\r\nConfiguration passed to `start` is expected to contain `flags` (which some data that is just forwarded to) `init` function, `update`  and `view` functions.\r\n\r\n- `init` supposed to construct initial state and request any kind of side effects (usually io task) to be performed to bootstrap. There for it returns `[model, fx]` pair.\r\n\r\n- Initial `model` then gets rendered via `view(model, address)`. Where `model` is whatever the immediate state of the app is and `address` is a function that could be used to trigger more updates. Any user just passes `action` describing it to the `address`. In turn received `action` triggers `update(model, action)` that supposed to return `[model, fx]` pair like `init` did. View itself returns virtual-dom describing the application UI.\r\n\r\nOne 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.\r\n\r\n### `signal.js`\r\n\r\nProvides 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`.\r\n\r\n### `task.js`\r\n\r\nProvides 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.\r\n\r\n### `effects.js`\r\n\r\nThis 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`.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/mozilla/reflex/issues/comments/227229360","html_url":"https://github.com/mozilla/reflex/pull/46#issuecomment-227229360","issue_url":"https://api.github.com/repos/mozilla/reflex/issues/46","id":227229360,"user":{"login":"Gozala","id":21236,"avatar_url":"https://avatars.githubusercontent.com/u/21236?v=3","gravatar_id":"","url":"https://api.github.com/users/Gozala","html_url":"https://github.com/Gozala","followers_url":"https://api.github.com/users/Gozala/followers","following_url":"https://api.github.com/users/Gozala/following{/other_user}","gists_url":"https://api.github.com/users/Gozala/gists{/gist_id}","starred_url":"https://api.github.com/users/Gozala/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gozala/subscriptions","organizations_url":"https://api.github.com/users/Gozala/orgs","repos_url":"https://api.github.com/users/Gozala/repos","events_url":"https://api.github.com/users/Gozala/events{/privacy}","received_events_url":"https://api.github.com/users/Gozala/received_events","type":"User","site_admin":false},"created_at":"2016-06-20T18:34:09Z","updated_at":"2016-06-20T18:34:09Z","body":"@tschneidereit does it still makes sense to keep this one open ?"}}
{"actor":{"display_login":"Gozala"}}