Open aronallen opened 7 years ago
Perhaps best that you write an initial proof of concept PR.
@aronallen Patched vdom trees as streams.
I don't think that sounds insane. If you have further thoughts on this, I'd want to hear them.
Also and just to make sure I'm on the same page, what do you mean by I/O in this case?
@jbucaran by I/O i mean the overhead in the communication between the web worker thread and the main thread.
@jbucaran
basically I want a flat list of mutations. something like
[
['remove', [0,2,1,2,5,1]],
['add', [0,2,1,2,5,1], node],
['update', [0,2,1,2,5,1], node]
]
The coordinates must be defined so that they assume all previous mutations in the same patch have happened
I really hope this happens! I have been looking for a way to have diff and patch split up for a long time for that exact usecase.
Aron Nyborg Allen wrote:
Hi,
As some may know I am experimenting with running Cycle in WebWorkers. It works pretty well, but the main bottleneck is the postMessage API. Right now I am transmitting something i call vDOMSON, representing the entire component vTree, this is then mapped recursively to |snabbdom/h| which in turn is passed to the patch function.
To reduce I/O I thought it could be neat to have patch in two parts, so instead of transmitting the entire vDOMSON, I can just transmit a list of mutations. The pre-patch could be run in the sub-thread, while the resulting mutations could be applied in the main thread.
I know it sounds kind of insane.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/snabbdom/snabbdom/issues/231, or mute the thread https://github.com/notifications/unsubscribe-auth/AIRy02NhFYlIl9Zvz2pzEylNbVgGkrMrks5rTgpAgaJpZM4Lm2HZ.
@aronallen check out snabbdom's DOMAPI
. It's essentially a wrapper for anything that actually touches the real DOM. Perhaps you can send serializations that refer to calls of those methods.
interface DOMAPI {
createElement: (tagName: any) => HTMLElement;
createElementNS: (namespaceURI: string, qualifiedName: string) => Element;
createTextNode: (text: string) => Text;
insertBefore: (parentNode: Node, newNode: Node, referenceNode: Node | null) => void;
removeChild: (node: Node, child: Node) => void;
appendChild: (node: Node, child: Node) => void;
parentNode: (node: Node) => Node;
nextSibling: (node: Node) => Node;
tagName: (elm: Element) => string;
setTextContent: (node: Node, text: string | null) => void;
}
The cool thing about snabbdom is that you can pass an instance of domAPI
to init()
.
I know some of these methods take Element
as argument, but this is actually vnode.elm
, so it could be that vnode.elm
on the web worker side is just some kind of virtual pointer (a string, if nothing else) to an element on the DOM.
Just an idea...
@staltz thanks for the hint.
If the DOM API only received virtual DOM nodes, and expected virtual DOM nodes it would be quite easy to port. I guess I could write a shallow implementation of <Node>
in the webworker context.
@aronallen
If the DOM API only received virtual DOM nodes, and expected virtual DOM nodes
My two cents. The domapi is just but an object exposing the functions in staltz post above. Snabbdom implements this api using the function in document.* by default, but the idea is you can provide an object with your own implementation.
const patch = require("snabbdom").init([/* modules */], myDOMAPI)
@jbucaran yes, it is pretty neat. I think I can put something together.
This may open the way for multi-threaded UI in snabbdom itself? Is snabbdom ever a bottleneck in that regard? Even if used correctly?
@mightyiam I don't know, my idea of using web workers is more about security by providing an encapsulated execution context. Since everything needs to be patched in the main thread anyway, I wouldn't imagine there to be any performance benefits. So there might be performance benefits, but I doubt it.
There is some performance benefit.
If diffing takes a long time, the ui/scrolling won't jank if it's done in a worker thread. See http://www.pocketjavascript.com/blog/2015/11/23/introducing-pokedex-org
Aron Nyborg Allen wrote:
@mightyiam https://github.com/mightyiam I don't know, my idea of using web workers is more about security by providing an encapsulated execution context. Since everything needs to be patched in the main thread anyway, I wouldn't imagine there to be any performance benefits. So there might be performance benefits, but I doubt it.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/snabbdom/snabbdom/issues/231#issuecomment-274183549, or mute the thread https://github.com/notifications/unsubscribe-auth/AIRy09bOBclJGIqk_33bXXhqinJ_Sor2ks5rUSXugaJpZM4Lm2HZ.
@aronallen Found about ReactDOM Stream and remembered this issue for some reason.
@whmountains have u seen passive event listeners https://developers.google.com/web/updates/2016/06/passive-event-listeners
@aronallen title change OK with you?
Hi,
As some may know I am experimenting with running Cycle in WebWorkers. It works pretty well, but the main bottleneck is the postMessage API. Right now I am transmitting something i call vDOMSON, representing the entire component vTree, this is then mapped recursively to
snabbdom/h
which in turn is passed to the patch function.To reduce I/O I thought it could be neat to have patch in two parts, so instead of transmitting the entire vDOMSON, I can just transmit a list of mutations. The pre-patch could be run in the sub-thread, while the resulting mutations could be transferred to and applied in the main thread.
I know it sounds kind of insane.