Sign in to follow this  
Sébastien Lorber

Optimizing a Pixi stage

Recommended Posts

Hi all

I'm totally new to Pixi, WebGL, Canvas... and actually I'm not making a game but a React webapp, hope this is fine to post there...

 

What I want to build:
- Draw an image (A4 document scan, generally jpeg/png from 100k to 1m)
- On top of each word of the image, draw an interactive rectangle which can be hovered/clicked
- Thanks to deep learning/OCR, I already have the size of the image and the relative positions of the document words
- Documents can have from 0 to 3000 words
- Ability to zoom

image.thumb.png.fb234db4dab0550f2079eacb4bf43eca.png

 

I tried first with regular CSS, but clearly found out that using position absolute was not performant to position thousands of rectangles on the document: performance was not good on scroll for example.

I tried using PixiJS to draw the rectangles on top of the image. The result is better, but I still see some performance problems on my old computer, particularly when the image is zoomed (it affects scroll so it's not really related to JS code I guess)

Here is the result: https://dhatim-poc-mlhafeauav.now.sh/

Can someone tell me how to optimize this for older computers?
How can I audit the performance of this solution properly?
Is there an easy way to simulate an old computer on my dev env? particularly regarding GPU instead of CPU throttling?

 

The solution I used for the above document of
- An html img tag
- A transparent canvas sitting on top of the image, on which I draw the rectangles (Graphics, drawRect)

 

I tried to follow some recommendations found here: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas

- I use a background image instead of drawing the image to the canvas (not sure it has a large impact because there is no "game loop")
- I use Math.floor for the position of the words

 

Are there other recommendations you could give to have better performances?

Particularly:
- should I use a small canvas size and use a scale transform to handle the zooming? (see Mozilla perf link above)
- should I use Sprite or Graphics for the rectangles?
- should I use canvas or WebGL?
- how can I measure my performance optimizations? I currently feel I'm totally blind and not even sure that what I do produce a better result without concrete numbers

 

Edit: here is a version with a canvas scale transform: https://build-ybbdwoumva.now.sh/

 

Thanks

 

 

 

Share this post


Link to post
Share on other sites

Pixi renders everything every frame. The first thing to do is to clone Application class, its supposed to be helper for hello-worlds, not for apps of your scale.

https://github.com/pixijs/pixi.js/blob/dev/src/core/Application.js

Then, in "render" method you can add a dirty flag.

For zoom, you have to change container position/pivot/scale transform, you have to learn how they work. Sorry, no tutorials about them, only a big collection of forum posts, search for "camera", "pivot", "zoom".

Share this post


Link to post
Share on other sites

I actually don't really know how to profile, particularly on an old computer on windows, which tools should I use for that?

Is there a way to not make pixi re-render on every frame?
Because I usually need only a single render, and then only re-render on special events like using zoom or browser window resizes (these events may not actually happen very oftenly in my app)
Is that what I should do by cloning the Application class? I'll look at this soon

 

About zoom/resize, I've actually made an attempt here where I use a fixed-size canvas and use css scale transform on it: https://build-ybbdwoumva.now.sh/
Unfortunately I have no access to slow computer to see if this makes any difference, is there anything I can do to see if it improves the situation on my macbook pro, which is too fast to experience the performance issues?

 

 

 

 

Share this post


Link to post
Share on other sites

Chrome has a pretty good profiler. Hit F12 to get debug console, then go to performance, hit record and gather some info. Here's an example screenshot from the page:

image.thumb.png.2de35c25af04dbdca3ec7d56a377f69d.png

I have a single frame selected in that which had a lot more stuff happening than what the ones nearby. You can see that most of that frames time has gone to event handling. And I most likely clicked either zoom or text at that frame. Rendering seems pretty ok in my mind.

You can make pixi render only wanted frames as Ivan suggested, instead of using application, create your own ticker and rendererer and then have some boolean flag dirty and set it to true everytime user does something. If it's true, then render in requestAnimationFrame and set it to false. If it's false then just skip render on that RAF.

Share this post


Link to post
Share on other sites

Oh and the scaling change will make a difference for slower computers. Before scaling you had over 4k resolutions to render when zoomed. Now the rendering is done to whatever the canvas is originally and then the result is scaled up similarly as how images would be scaled.

Share this post


Link to post
Share on other sites

> Is there a way to not make pixi re-render on every frame?

 

Pixi only renders when you call .render() on the Renderer instance. If you use Application, this is happening for you already and Ticker has some helper functions/properties to control the update rate. But if you only want to render a new frame when something changes, just don't use Application and create your Renderer manually.

Share this post


Link to post
Share on other sites

Thanks everyone for the advices.

I'm currently using this React pixi lib (which use an Application) but will maybe try raw pixi to have more control over re-renders.

Actually I've noticed performance problems on one old computer, when using a large canvas (100% of a large screen) and when drawing the image to the canvas.

I'm currently traveling and don't have opportunity to test on that computer again, but using another old computer and different tests I've done, it seems to work pretty well now... so maybe most of my issues have been fixed. Will keep in mind your advices if I need further optimizations.

 

Thanks

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.