Skip to content
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

Move layout functions to Web Worker for pixi.js examples #20

Closed
gouldingken opened this issue Sep 12, 2015 · 12 comments
Closed

Move layout functions to Web Worker for pixi.js examples #20

gouldingken opened this issue Sep 12, 2015 · 12 comments

Comments

@gouldingken
Copy link

I saw you mentioned in another issue that you were planning to move some functions to web workers in one of the other threads. This seems especially important for the pixi.js examples where layout is currently being done in the render loop.

I don't know if you've tried this yet, but I did a quick test of putting the layout function in a web worker. I don't have any performance comparisons, but I'm doing some more graphically intensive stuff in Pixi.js so I'm getting about 18 fps on the render loop. The layout loop on the worker is running at around 40fps. This ensures a much quicker (and consistent) layout resolution time while still keeping a reasonably smooth graphics performance. Its working well enough that I thought it was worth posting an issue here. I can extract and share the relevant code if that's helpful.

@anvaka
Copy link
Owner

anvaka commented Sep 12, 2015

Very interesting! Do you have an example to share?

@gouldingken
Copy link
Author

Yes. Actually I tweaked it some more and it's up to 100 layout cycles per
second. It seems the amount of data sent between the threads matters. I
have one more optimization to try then I will push it to git and share with
you -hopefully tomorrow as it's getting late here EST.

Thank you so much for your work on this. The modularity and speed are a
game changer for me. I've used d3 and sigma for a while now but have always
been limited by the number of nodes I can show and have had to resort to
Java (GephiLib + Processing) to show real time visualizations.

I'm very excited about the potential of ngraph plus pixi!
On Sep 11, 2015 11:29 PM, "Andrei Kashcha" notifications@github.com wrote:

Very interesting! Do you have an example to share?


Reply to this email directly or view it on GitHub
#20 (comment).

@gouldingken
Copy link
Author

Here's the example:
https://github.com/gouldingken/pixi-ngraph

@anvaka
Copy link
Owner

anvaka commented Sep 13, 2015

Thanks for the demo!

I forked you repository and extracted web worker code into plain javascript file to compare FPS of the two approaches.

To get accurate FPS measures I'm using built-in tool inside Chrome: Dev tools -> then press ESC key to bring up a drawer from the bottom and -> Click Rendering tab and select "Show FPS meter":

image

https://anvaka.github.io/pixi-ngraph/index.html - this is unmodified version with layout inside web workers
https://anvaka.github.io/pixi-ngraph/index-plain.html - this version computes layout inside requestAnimationFrame()

I couldn't see much difference between them, but maybe I'm missing something. Do you get better results on your end?

@gouldingken
Copy link
Author

Thanks for putting those comparisons together. Yes I see a huge difference! In the second example, it takes a full minute for the layout to fully resolve (1000 cycles). In the first example it takes less than 8 seconds!

In both cases the FPS will be about the same because that's just measuring the render cycles.

The problem I'm trying to solve is that I want my users to be able to see (and start interacting with) the final layout a lot more quickly. I don't want them waiting a full minute for it to get to that point while they watch things slowly laying out.

@stevenalowe
Copy link

Fwiw the layout with web workers is much smoother and seems faster on iPhone safari

--S

On Sep 13, 2015, at 3:58 PM, Andrei Kashcha notifications@github.com wrote:

Thanks for the demo!

I forked you repository and extracted web worker code into plain javascript file to compare FPS of the two approaches.

To get accurate FPS measures I'm using built-in tool inside Chrome: Dev tools -> then press ESC key to bring up a drawer from the bottom and -> Click Rendering tab and select "Show FPS meter:

https://anvaka.github.io/pixi-ngraph/index.html - this is unmodified version with layout inside web workers
https://anvaka.github.io/pixi-ngraph/index-plain.html - this version computes layout inside requestAnimationFrame()

I couldn't see much difference between them, but I maybe I'm missing something. Do you get better results on your end?


Reply to this email directly or view it on GitHub.

@gouldingken
Copy link
Author

Thanks Steven. I hadn't thought to try it on mobile. FWIW I just tried on my old HTC and it renders at around 4fps, but lays out at around 20 loops per second. It's not fast by any measure, but the difference between the 2 methods is accentuated.

@anvaka
Copy link
Owner

anvaka commented Sep 14, 2015

Ah, thanks for the clarification. I see a lot of value in your use case.

I'm going to create a force layout wrapper to perform computation in the web worker if possible.

PS: Regarding

I saw you mentioned in another issue that you were planning to move some functions to web workers

I was trying to optimize FPS, not number of iterations, when I made this experiment 6 months ago. But your idea makes much more sense!

@gouldingken
Copy link
Author

Thanks Andrei.

@anvaka
Copy link
Owner

anvaka commented Sep 24, 2015

https://github.com/anvaka/ngraph.asyncforce here is a first draft. Please take a look. Not sure if I like the API...

@gouldingken
Copy link
Author

This looks great. I like that you've included ways to communicate pinning and other options across to the layout worker.

One thing I don't really understand is why you are calling layout.step(); within the render loop. Why is this necessary? Can the layout not just keep looping of its own accord?

Thanks for all your work on this.

@anvaka
Copy link
Owner

anvaka commented Sep 26, 2015

There are couple reasons:

  1. When you execute everything in the web worker - it doesn't know when your page is not active. Thus it keeps running CPU intensive computation even when you look at something else. This will quickly kill a battery on laptop or mobile device. By having step() operation you are giving worker a hint, that page is still active.
  2. I wanted to make it backward compatible with regular ngraph.forcelayout.

If you don't like this behavior but prefer to compute N iterations of layout, you can tweak waitForStep option. See full example here: https://github.com/anvaka/ngraph.asyncforce/blob/master/demo/vivagraph/index.js#L19

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

No branches or pull requests

3 participants