Jump to content
Search Community

Tools and tips on debugging slow performing animation

Good Looking Software test
Moderator Tag

Go to solution Solved by GreenSock,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

My animation is slow but my various browser debugging tools don't show where the delay is happening.

 

I will post again with specifics and a Codepen if this fails, but could someone take a look at my animation and tell me how they would approach understanding its performance? What tools do you use to see how long things are taking, how memory is being used, and where the bottlenecks are?

 

http://catalyst.goodlookingsoftware.com/a/

 

Many thanks,

Aaron

 

 

Link to comment
Share on other sites

  • Solution

Performance audits can be really complex and demanding. I don't have time to dig into an overall audit, but I'll offer a few things:

  1. The bottleneck in situations like this is almost never the animation engine (GSAP in this case). Graphics rendering is by FAR the biggest bottleneck (literally like 100:1 ratio). So focus your attention there.
  2. It looks like your interface is almost entirely SVG, but since SVGs are resolution-independent, that means that all of the pixels must by dynamically fabricated on-the-fly...on every frame...60 times per second. You've got a LOT happening that requires the browser to fabricate a lot of pixels. You'd probably get better performance if you used raster images (like PNGs) instead of SVG. 
  3. Try to keep the area of change as small as possible to minimize repainting. 
  4. Consider only changing z-index when it's absolutely necessary and will make a visual difference. It just makes it easier on the browser's graphics rendering algorithms. 
  5. Only use transforms to move stuff (which it looks like you're doing well). 
  6. You may get better performance by building this in <canvas> because it's so much easier on the browser. It doesn't have to worry about all the DOM nodes and their properties, event dispatching, etc. Note: you can use GSAP to animate pretty much anything, including canvas library objects.
  7. Disable pointer-events on as much as possible. 

I hope that helps!

  • Like 3
Link to comment
Share on other sites

Thanks for all of this!

 

For #4, any tips? I use the z-index a lot. For example, should I do extra math to ensure the z-indices are only incremented at intervals? Should I try to limit the frequency any z-index is changed or how many z-indices change when any z-index is changed?

 

For #6, do you mean that I should wrap the animation elements in a canvas tag or is there more to it than that?

 

For #7, do you do this in the css? pointer-events: none; I do that for elements that intercept pointer events, but should I be doing that on any element I possibly can?

 

Thanks again. Very helpful!

 

Aaron

Link to comment
Share on other sites

#4: yes, I just meant change it as infrequently as possible. You'd need to figure out the logic in your particular circumstance (I just don't have time to dig through it all). But this may not yield a lot of performance benefit anyway, so you might just want to do a few tests before you burn a bunch of time re-jiggering your code. It's probably the least likely to pay dividends. 

 

#6 absolutely not. It's much more complicated than that. You can't just wrap SVG in an <canvas> tag and expect it to eliminate all those DOM nodes and draw things inside the canvas. You'd literally have to rebuild it in canvas completely, probably with a canvas library to make it easier. This is no small undertaking but it would likely pay the biggest dividend performance-wise. Again, I'd encourage you to do some tests before burning a ton of time rebuilding from scratch. To be clear, the performance difference has absolutely nothing to do with GSAP - it's purely about the rendering layer in the browser. Actually, if you go with a canvas library, you might want to consider something like PixiJS because it could leverage WebGL which is insanely fast. 

 

#7, yes, I just meant pointer-events: none. Glad you're already doing that. 

 

Good luck! :)

Link to comment
Share on other sites

A really great library for converting SVG to canvas is Frabric.js. It can even do the conversion server-side using node. Graphically you won't be able to tell the difference, but you'll definitely notice the difference when it comes to animations. This demo pretty much sums up the performance difference.

 

SVG Caching: http://fabricjs.com/svg-caching/

  • Like 3
Link to comment
Share on other sites

Just to add my two cents about question #4

 

Besides using z-index you can also try and change the stacking context of elements by doing any of the following:

 

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

 

A stacking context is formed, anywhere in the document, by any element which is either

 

- the root element (HTML),

 

- positioned (absolutely or relatively) with a z-index value other than "auto",

 

- a flex item with a z-index value other than "auto",that is the parent element display: flex|inline-flex,

 

- elements with an opacity value less than 1. (See the specification for opacity http://www.w3.org/TR/css3-color/#transparency),

 

- elements with a transform value other than "none",

 

- elements with a mix-blend-mode value other than "normal",

 

- elements with a filter value other than "none",

 

- elements with isolation set to "isolate",

 

- position: fixed

 

- specifing any attribute above in will-change even if you don't specify values for these attributes directly,

 

- elements with -webkit-overflow-scrolling set to "touch"

 

Sometimes when using 2D or 3D transforms z-index will not work. So the workaround is one of the above techniques, to give your element a new stacking context. Which will put that element on a new render layer.

 

To test performance you can use Chrome Dev Tools in the browser

 

https://developers.google.com/web/tools/chrome-devtools/?hl=en

 

Firefox and IE also have Dev Tools, but Chrome has much better tools to test with. Also when testing for performance make sure you are testing in incognito mode or private browsing mode so you don't skew results :)

  • Like 2
Link to comment
Share on other sites

I'm not seeing a critical piece: a way to send mouse events through the transparent portions of stacked elements down to the first visible opaque element.  Do you know if fabricjs or another library can handle that? Would this be instead of GreenSock?

 

I'm trying to figure out if my best chance at success is to shrink and simplify what I have or port it to something like fabric.

 

Thanks again,

Aaron

Link to comment
Share on other sites

I don't know enough about the event system in Fabric to answer that. I'm actually more familiar with Pixi, which Jack suggested. But by transparent, do you mean it's not visible? If so, what are you using them for? If they are transparent because you are hiding them, you could just remove them from the canvas and add them when needed. Kind of like setting display: none in CSS.

Link to comment
Share on other sites

Thanks, OSUBlake. I'm going to give fabric a shot this week and report back with my findings. There's a fabric setting--something like perPixelSelect--that tells fabric to only use the opaque part of an image for mouse events. That's what I was getting at with the transparency stuff. I've got 30 images stacked that are mostly transparent except for the image or a tree root that passes through it.  So, the root visible to the user might be 10 images down the stack. 

Link to comment
Share on other sites

I figured Fabric would have something like that. With canvas you can check the color of a pixel, which is pretty powerful. Here's a demo where I do that to test for collisions on an SVG. If the color of a pixel is black where the box is, that means there's a collision. It sounds like that is what Fabric is doing.

 

See the Pen YypwzL by osublake (@osublake) on CodePen

Link to comment
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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...