Skip to content

#113 - Implement experimental web worker support #114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Dec 10, 2016
Merged

#113 - Implement experimental web worker support #114

merged 14 commits into from
Dec 10, 2016

Conversation

treshugart
Copy link
Member

@treshugart treshugart commented Dec 1, 2016

Implements #40, #113.

@@ -1 +0,0 @@
require('skatejs-build');
Copy link
Member Author

@treshugart treshugart Dec 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boyscout: totes unused.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build doesn't work now, is it because of this?

sd.diff({
destination,
source,
done (instructions) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the tentatively proposed API: provide a done callback and if workers are available it uses them. Still need to patch render / merge to handle this.

@@ -66,10 +66,12 @@ function translateFromReact (item) {
return item;
}

let count = 0;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely better ways, but this gets the initial spike working.

// import WeakMap from './weak-map';
// export default new WeakMap();
const map = [];
export default {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't use weakmaps if we're using scalar values as keys.


export default {
diff,
merge,
patch,
render,
types,
vdom,
version
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boyscout: removed this as it was way out of sync.

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@matthewp
Copy link

matthewp commented Dec 1, 2016

Hm, I don't have a node_modules/.bin/sk-build, is that something I need to install globally?

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@matthewp
Copy link

matthewp commented Dec 1, 2016

Are you using both rollup and webpack? Or maybe transitioning from one to another?

@matthewp
Copy link

matthewp commented Dec 1, 2016

About the API, I think it's a good API for a lot of use cases, but in my case I'm already running inside of a web worker, so I don't need to launch another worker. I'll be diffing 2 plain objects in the worker, sending the patch instructions back to the window and applying the patches there.

To keep my file-size down I'll probably use rollup, does the use of the webpack plugin here break rollup usage (even if you don't wind up using that functionality)? I could maybe just pull in dom-diff/src/diff-main.js directly since that's what I need on the worker since, then pull in dom-diff/src/patch.js on the window side.

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@treshugart
Copy link
Member Author

Fixed the rollup build issue. Now generating a dist/index.js with webpack and will add a min version soon.

@matthewp
Copy link

matthewp commented Dec 1, 2016

So, I don't know if you answered this, but since you are using jsnext config, a rollup user might do:

import { diff } from 'skatejs-dom-diff';

Will this work or blow up, aren't you using a webpack config in src/diff.js or am I just confused?

@treshugart
Copy link
Member Author

treshugart commented Dec 1, 2016 via email

@matthewp
Copy link

matthewp commented Dec 1, 2016

ids don't seem to work, I guess because it assumes your nodes are created with sd.vdom.element, right? So that means it only works with patching 2 vdom nodes. You can't patch a real node against a vdom node or vice versa.

Also, if one Node is created in the worker and another in the window their ids aren't going to match up. I'm pretty sure this is why React has ids that look like 0.1.14.2.3, it's really a path to find the Node. That's the only way to find the same Node from another tree.

I wrote a library for this purpose about a year ago: https://github.com/canjs/node-route/blob/master/src/dom-id.js The inline docs do a decent job of explaining what is going on. Of particular interest are nodeRoute.getID(node) which gives you that id like "0.1.14.2.3". And other is nodeRoute.getNode(id, root) which will find the Node for a given id. Notice that it uses firstChild and nextSibling which your vdom doesn't have, so its not something you could drop in and use unfortunately. But could be a guide if you wanted to use it.

This could wind up being a bigger change that you were probably anticipating, I imagine, so I would understand if you don't want to pursue it further.

@treshugart
Copy link
Member Author

ids don't seem to work, I guess because it assumes your nodes are created with sd.vdom.element, right? So that means it only works with patching 2 vdom nodes. You can't patch a real node against a vdom node or vice versa.

This is intentional as there's no way to transfer a DOM node from the real DOM to a web worker. A way around this would be to extract information from each node and give it an id at that point in time. Unfortunately this would involve building a virtual tree from the entire real tree on the main thread. Basically the inverse of the vdom/dom function. This might be worth doing if performance isn't the main concern, which there's definitely use cases for, but if that's the case, then why use web workers?

What's the use case for needing to diff a real tree in a worker?

@matthewp
Copy link

matthewp commented Dec 2, 2016

You need to construct a virtual tree from the real tree once, when the page loads, if you ever intend to patch the real tree. I want to build the virtual tree on page load, send it to a worker, and from that point on only patch that virtual tree against other virtual trees, sending the patch instructions back to the window and applying the patches on the real tree.

@treshugart
Copy link
Member Author

treshugart commented Dec 7, 2016

@matthewp

Massive update. I've added both toDom() and toVdom() to convert between real and virtual trees. You should be able to do something like:

import { diff, toVdom } from 'skatejs-dom-diff';

const vTree = toVdom(document.getElementById('app'));
diff(vTree, myNewTree, {
  done (instructions) {
    patch(instructions);
  }
});

That said, the render() function now supports doing all that; so it will take the root node you provide it and convert it to a virtual tree before diffing and patching. It also supports the done function for diffing in a worker:

import { render } from 'skatejs-dom-diff';

const renderer = render(root => (
  <div>I was rendered in {root.id}!</div>
));

renderer(document.getElementById('app'));

Understand if you've moved on, but I've quite enjoyed just tinkering on it. Fun project.

@matthewp
Copy link

matthewp commented Dec 7, 2016

Yeah no doubt, I think this is a real differentiator for the project, as I've explored all of them just about and most do not break out diffing and patching in this way.

I'm happy with idom but definitely am not married to it. I have plans for creating benchmarking for vdom through web workers approaches. In the meantime I still have a branch of my project using dom diff so I'll try out these changes and let you know.

@treshugart treshugart merged commit 766e774 into master Dec 10, 2016
@treshugart treshugart deleted the 113 branch December 10, 2016 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants