Jump to content
Search Community

Convert CSS3 animation to GSAP for performance gain

Dx802 test
Moderator Tag

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

Hey Guys,

 

I'm pretty new into GSAP, but based on an advise of a friend I'm posting this question on this forum.

I need a series of animation to run on a rather low end pc (intel atom - windows 10 - 2 gig ram).

 

I used CSS3 animations as I assumed the hardware acceleration was the best there.

The result can be found on (https://jsfiddle.net/p0deznot/ --

See the Pen RaJRaE) by Dx802 (@Dx802) on CodePen

 

Its made for a fullHD screen (no need for responsiveness). The problem is that the performance is not as good as hoped, especially on the curved line reveal.

 

Is it possible to convert these animations to GSAP ? If so, where do I start ....

 

The animations are pretty simple

 

- Container flips in (0% opacity to 100% 3d transform)

- Content of container is revealed (curved line reveal)

- Content is animated a bit (opacity, move, ...)

 

Any chance anybody hint me if performance could be better with GSAP ? Or point me in the right direction to try these same effects in GSAP ?

 

Many thanks

See the Pen RaJRaE by Dx802 (@Dx802) on CodePen

Link to comment
Share on other sites

Hi Dx802,

 

Welcome to the forums. 

 

As to your question. Converting that to GSAP would be fairly simple. Whether it yields performance gains, only testing will tell. 

 

The thing with animation in the web is how much "paint" and "reflow" the browser has to do. I won't get into details because I don't know much myself and would not like to misguide anyone. What I know is that the cheapest types of animation are transforms and opacity. The more you avoid using the other properties, the better.

 

I would suggest the getting started post - that will run you thru the basics and get you up to speed. After that, we can go over the details of your animations (like, text animation, the curved reveal, etc).

  • Like 4
Link to comment
Share on other sites

Also, be mindful about how many pixels you're pushing around the screen at any given time; typically in cases like this the biggest bottleneck BY FAR is the graphics rendering which the browser is responsible for, thus it has nothing to do with GSAP (or even CSS animations). So, for example, GSAP might do all of its work and only sip 1% of the CPU, but then the browser might take 99% to calculate all the individual pixels and paint them to the screen. If you keep the area of change as small as possible (visually), you'll get better results. From your codepen, it looks like you're basically making the browser repaint the entire screen (all the pixels) constantly during the animation which might be fine on beefier mobile devices and desktops, but it certainly explains why you might see poor performance on low-end mobile devices with limited processing power. 

  • Like 6
Link to comment
Share on other sites

Also i noticed your CSS transition property is set to animate all instead of just specific CSS properties like transform, top, left, and opacity.

 

But when animating, you should always animate with x and y over left and top. Animating position offsets like top and left can cause layout recalculations which then trigger repaints and re-compositing, can also cause bad performance.

 

x and y will always animate better since it can take advantage of using hardware acceleration (GPU). Instead of using the CPU with top and left with constant re-calculations on every tick.

 

Some useful and helpful article on why x and y are better than animating top and left.

 

https://css-tricks.com/myth-busting-css-animations-vs-javascript/

 

Check this website out to see what CSS properties trigger layout, paint, and compositing in the browser:

 

http://csstriggers.com/

 

:)

  • Like 6
Link to comment
Share on other sites

I used CSS3 animations as I assumed the hardware acceleration was the best there.

 

A lot of people believe this, but it's more about how you're doing the animation rather than what you are using. Driving a really fast sports car does not give you a guarantee that you will reach your destination before someone else.

 

As Jack pointed out, the problem is caused by constant browser repaints. I think understanding what causes a repaint can be a little confusing if you aren't familiar with GPUs.

 

Here's the basics. The browser paints your DOM elements as a bunch of textures and uploads them to the GPU's memory. Think of a texture as an image or screenshot of your element, just a bunch of pixel values. Now that the texture is stored in the GPU's memory, it can work it's magic and do those super fast matrix calculations. The texture will stay in memory as long as the only changes to it are transforms, opacity, and a couple CSS filters.

 

If you change another property, like its color, or in your case, a clip-path, the texture has changed and must be destroyed. The browser has to create a new texture and upload it the GPU, and that's the bottle neck. Your clip-path is destroying its texture on every render and has to be repainted.

  • Like 8
Link to comment
Share on other sites

Let me add that you can still optimize destructive animations by putting them on different layers. Understanding layers can be confusing as it might not be obvious what elements are on them and how they are created. I'm sure @Jonathan could provide more insight into this if needed. He's like a Layerologist or something.

 

 

k7457Wn.jpg

 

Just think of layers as the cels used in a hand-drawn animation. The background usually doesn't change as much as stuff in the foreground, so you can save time by drawing it on a different layer. Imagine how long it would take to create an animation if the animator had to redraw a complicated background as many times as he did with some of the foreground elements.

 

That's the same thing that is happening when the browser has to repaint the entire screen. So put elements that need to be redrawn more often on separate layers. But don't create too many layers as that will create additional overhead, and will start eating up all your memory.

  • Like 3
Link to comment
Share on other sites

A similar question was asked here.
 

My assumption is there is not much more that can be done, as I'm already making the top layer render as its own layer in the GPU via 3D CSS

 
That is actually one of the worst things you can do to improve performance. The GPU has limited memory and can only animate transforms, opacity, and some CSS filters. Anything else, and it has to be offloaded from the GPU, repainted, and uploaded back onto the GPU. When you put stuff on the GPU that it can't animate, you're causing unnecessary repaints which may be less efficient than just keeping it on the CPU.
 
 

When the cover image (SVG clip path) is tweened to reveal the next cover image, sometimes there will be jank. This is especially true on high-res devices. On normal-res devices the jank is far less noticable, but still poses a problem. What can I do to reduce jank when tweening image over image?
 
visitmexico.bvkdev1.com

 
Animating SVG is really slow. Here's a trick I came up with for a clip path, nest your content inside another element, and animate their xPercent/yPercent against each other. 

See the Pen 6646d7d2b5ba66947cee139bd7a4ff55 by osublake (@osublake) on CodePen

 

And here's another cool trick. You can't animate color on the GPU, but you can fake it. Find out the secret...

See the Pen ofDIh by ariya (@ariya) on CodePen

 

And a glow...

See the Pen nFADe by ariya (@ariya) on CodePen

  • Like 5
Link to comment
Share on other sites

@-webkit-keyframes plainbox {
    0% {
        opacity: 0.5;
    }


    100% {
        opacity: 1;
    }
}

Blake, I need your badge on my desk right NOW!

 

 

;)

 

 

those are great tips. thanks for sharing.

  • Like 4
Link to comment
Share on other sites

@-webkit-keyframes plainbox {
    0% {
        opacity: 0.5;
    }


    100% {
        opacity: 1;
    }
}

Blake, I need your badge on my desk right NOW!

 

Now why would I go and do a silly thing like that? I guess I should have pointed out that I didn't come up with the color and glowing ones.

Link to comment
Share on other sites

Thanks for the warm welcome & the interesting insights. Didn't expect such a fast reactions, hence the late reply.

 

If I analyse correctly, our biggest enemy here is the reflow, which should be less relevant as its a fixed position non responsive animation.

I don't understand why painting would be an issue here; If I change the curved line reveal to a linear one, performance goes up, although it are still the same amount of pixels to be drawn in a comparable timeframe, not ?

 

I did some tests on both the CSS and the GSAP approach.

 

CSS: To ensure the elements are rendered on a seperate layer, I added the following to all the divs

 - backface-visibility: hidden;

 - will-change: transform, opacity; /* or others*/

 - position: fixed;

 

The result can be found on

See the Pen LNJGJo by Dx802 (@Dx802) on CodePen

It looks more performant, but still the GSAP seems to win

 

GSAP : 

See the Pen PNdZXz by Dx802 (@Dx802) on CodePen

- Its not the exact same animation; I wasn't able to match the exact 3d transform and was not able do the curved line reveal

 

- It looks like using the CSS 3d transform wasn't just transferable to GSAP. Any tool like http://ds-overdesign.com/transform/matrix3d.html available for GSAP ?

- The curved line reveal, I'm a bit uncertain there how to get this working in GSAP Any good places to start looking ?

 

Seems to be very good on framerates even on slower hardware; ofcourse the animation is only at half of the process ;-)

Link to comment
Share on other sites

Transforms work a little different in GSAP. I'm in a rush, so I'll let somebody else handle that.
 
It's not the reflows that are the problem, its the repaints. A repaint has to calculate all those pixel values, which can be a very expensive process. If your screen is 1000x1000, that's 1,000,000 pixels.
 
Here's a demo I made to fill in the color of an image using canvas, which requires changing each pixel value one at a time. You can see that it doesn't animate smoothly when you change the sliders. I had to debounce the updates to 50ms because it was so slow.

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


 
That's the same problem the browser has to deal with it. The browser can optimize repaints using something similar to dirty rectangles, so it will only update areas of the screen that have change. But if your entire screen has changed, there's not a lot optimization that can take place.

 



  • Like 3
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...