Jump to content
GreenSock

scubajosh

CSS3 Plugin for hardware accellerated devices

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

I want to make a plugin for CSS3 hardware acceleration support for greensock. Does anyone have a project like this started already this is the weekist link in greensock right now for mobile devices and I dont want to scrap greensock on mobile because of the chug. Also I am interested in plugin primer scripts and what spots I should have this plugin overide in greenock to give maximum performance gains. Any help advice or code started would be apreciated.

 

 

Link to comment
Share on other sites

Be cautious about believing the hype out there about hardware acceleration and CSS3 animations. 

 

GSAP is extremely optimized and fast already, and the only place you might be able to see a difference performance-wise with CSS3 animations is with 3D transforms under heavy stress on iOS devices. In most of my tests, GSAP was actually FASTER than CSS3 animations for normal (non-transform) properties, like top/left. There's a ton of misinformation out there, so I'd recommend that you do your own real-world tests. 

 

There are major challenges with CSS3 animations, like:

  1. They provide almost no runtime controls. What if you want to seek(), pause(), resume(), reverse(), or alter the timeScale()? Most of this is absolutely impossible. With GSAP, it's easy. So if you build a plugin, how will you accommodate changes to timeScale, for example? What will you do if the user calls reverse() or seek()?
  2. They cannot accommodate eases like Bounce, Elastic, or SlowMo. How will you handle that in your plugin? 
  3. All transforms (x, y, z, rotation, rotationX, rotationY, scaleX, scaleY, skewX, skewY, etc.) are mashed together into a single "transform" property which means you cannot control them independently. So, for example, what if someone does this:
    TweenLite.to(element, 5, {rotation:360});
    TweenLite.to(element, 3, {scaleX:2, delay:3, ease:Cubic.easeInOut});

    It's impossible in CSS3 animations. See how the timing of the scale and rotation are different? And they use different eases? So if you build a plugin, how would you do this? 

  4. They can't handle overwriting or fine-tune control over individual properties getting killed. For example, what if you've got a top/left tween going, and the user wants to kill just the "left" portion but let "top" continue? 
  5. They cannot accommodate features like rounding.
  6. What about if people want to animate along a Bezier path and use autoRotate? Again, this type of thing is absolutely impossible with CSS3 animations (well, unless you created an insane number of keyframes to try simulating it, but that'd probably have a big cost performance-wise). 

I experimented with doing some conditional logic inside CSSPlugin and creating CSS3 transitions whenever certain criteria are met (like if the ease is a "legal" one for css, if timeScale is 1, if nothing fancy is getting animated like Bezier stuff, etc.) and then simply watch for if/when any "illegal" things occur (like changes to timeScale or reverse or seek) in which case it'd automatically fall back to standard JS, but even with almost no conditional logic in place yet, performance was actually WORSE with CSS animations.

 

Also keep in mind that there's typically only "hardware acceleration" for a few properties that don't affect document flow, like transforms and opacity. So it isn't as though CSS animations suddenly deliver massive speed boosts to all properties. It simply isn't true. And again, in the vast majority of my tests, GSAP was faster than CSS transitions/animations. The only time I noticed a difference in favor of CSS animations was on iOS when doing 3D transforms under heavy pressure (lots of simultaneous tweens). In most real-world scenarios, I doubt you'd notice any difference. Plus, in almost every case that I've seen stuttering, the bottleneck has nothing to do with calculating the animated values on each frame - it's graphics rendering in the browser. 

 

For example, if you're animating a huge image, the browser may only spend 1% of its effort on calculating the tweening values, and 99% on rendering the graphics, so in that case even if CSS animations boosted calculation speed by 1000%, the overall benefit would be negligible because 99% of its effort is still being spent on graphics rendering. 

 

One other tip: you can force the element onto the GPU (in most cases) even using GSAP by setting a very small "z" value or something. So, for example:

//if this is your original tween...
TweenLite.to(element, 1, {rotation:45});

//to force it onto the gpu, you can simply add z:0.1:
TweenLite.to(element, 1, {rotation:45, z:0.1});

The point is that when there's some sort of 3D piece of the transform, the browser, tries shoving it over to the GPU. Just don't go too crazy with this because there's an initial cost involved with pushing it to the GPU (this has nothing to do with GSAP - it happens for css too) and there's limited GPU memory. 

 

If you're seeing performance problems with GSAP, please do let us know. We're definitely focused on delivering maximum performance. 

 

Unfortunately, CSS animations just aren't good for professional-grade animation. Way too many limitations and shortcomings. I think that if you tackle this plugin endeavor, you may find that you're sacrificing a bunch of file size and features that are native in GSAP just to potentially eek out a little extra performance in 3D transforms on iOS. And maybe in iOS 7 Apple will have fixed the JS performance so that it's more like Chrome where optimized JS-driven transforms are as fast or faster than css-driven ones. 

 

Last note: check the speed test at http://www.greensock.com/js/speed.html and compare GSAP to Zepto because Zepto uses native CSS transitions (which of course also means it doesn't work at all in IE9 and earlier). On all the machines I've tested except maybe iOS, GSAP is faster. 

  • Like 4
Link to comment
Share on other sites

I see what you are saying and its the argument I been having with my co-workers but they did some tests for IOS devices like they have a carousel they wrote in greensock and one they used swipejs with and the greensock one was chuging on android and iphone while swipejs was smooth... I am trying to get them to put there test's on a jsfiddle so I can post.

Link to comment
Share on other sites

Yeah, I'd love to see a head-to-head codepen or jsfiddle because it may just be an issue of code that's written inefficiently or something. 

Link to comment
Share on other sites

So it appears that you have solved the problem my co-worker was having in another thread a few minutes ago. The solution to speed things up was to use x and y instead of using top and left. The only thing that we see a big difference in now is opacity being slow. So what if there was a plugin that hooked into the CSSPlugin to hardware accelerate Opacity on hardware accelerated devices? It seems allot eaiser to just support that since thats the last bottle neck I see in your code base for mobile devices. If you have it just as a plugin that extends the CSS plugin and overides __registerComplexSpecialProp method to check to see if you are on a hardware acellerated device then do CSS opacity it would pretty much solve every problem out there.

Link to comment
Share on other sites

I guess you found this fix in the other thread

 

Please see the cross post: http://forums.greens...ces/#entry29973

 

//just set z (or any 3D property) once to kick the element to the GPU
TweenLite.set(element, {z:0.1});
TweenLite.to(element, 2, {opacity:0.5});

Link to comment
Share on other sites

I'd like to share my personal experience re TweenMax performance on mobile.

 

On iOS (iPhone 4 - 5) GSAP runs smooth as oil - at least on par with CSS3 also on 3D transforms - but with a much, much greater flexibility and control. So there is no match on iOS, IMO.

 

On Android (>= 4.1.2 - don't bother with earlier versions), however, there is some noticeable difference with plain CSS3 transitions even on high-end hardware and simple animations. The same slide-out animation using Transit.js (a simple wrapper around CSS3 transitions) is a visibly smoother than GSAP - but then of course all animation control is pretty much lost. This is causing me some headaches because on the one hand I'd love to build the entire animation framework of my app around GSAP, but on the other the animations that really need to be super-fast are better with CSS3 transitions. Dilemma!

 

The example is very simple:

// This is a full-screen <div> with position: absolute;
$page = $(...);

// Using Transit http://ricostacruz.com/jquery.transit/
$page.transition({ x: '+=240', duration : 500 });

// Using GSAP
TweenMax.to($page, .5, { x: '+=240' });

// NOTE: I notice the same results if translateZ/{ z: .1} is
// used (in the CSS, in TweenMax.set or within the tween options)

 

You could try the simple test above on any of the latest Galaxy 3, Galaxy 4, Galaxy Tab2, HTC One - and you'd see that the GSAP version stutters a bit (it's still "fast" - but not "smooth") unlike the CSS3 version. After some investigation I reached the conclusion that there are 2 possible sources for this behaviour:

  • Perhaps the Android browser/GPU rendering engine handles ranged transitions from A->B better than a series of discrete matrix updates A->A1->A2...->An->B
  • The bottleneck may actually be DOM access - as GSAP needs to write into the DOM on every update (and then the new style needs to be applied/rendered) while the CSS3 transition is issued only once at the beginning

My current strategy on Android is to use GSAP whenever I need ultimate control - and fallback to Transit on "fire and forget" transitions (like the page slide above), but of course I wished there was a way to stick to GSAP  for everything...

  • Like 2
Link to comment
Share on other sites

Thanks for sharing your experience. It's quite helpful. Just curious: did you try forcing the element(s) to the GPU on Android by setting a 3D property like z? I've noticed that some browsers seem to yield better performance when something 3D is affecting the element. Instead of rendering things on the CPU, it can just pass the matrix3d() values to the GPU for compositing (rather than repainting). I have also noticed that in some webkit browsers, setting opacity to something other than 1 (like 0.99999) can boost performance. Again, I think it has to do with forcing it to offload some work to the GPU, and since the CPUs on those mobile devices are so underpowered, it seems to help.

 

Anyway, would you mind simply setting "z" to something small, like 0.1 and see if that helps you element(s) animate more smoothly on android? 

Link to comment
Share on other sites

Anyway, would you mind simply setting "z" to something small, like 0.1 and see if that helps you element(s) animate more smoothly on android? 

 

 

I've tried all possible combinations of gpu-triggers (in CSS classes, from TweenMax.set, inside the Tween options...) - like those you suggest and other tricks (setting perspective, hiding backface visibility etc.). In my setup clearly the gpu is kicking in (the difference would otherwise be huge). Plain CSS3 transitions are noticeably smoother in some cases (esp. visible in relatively long-range translations of large elements - like in the above example).

 

From what I can tell there is a connection between number of updates performed by GSAP and the smoothness of the result - which lead me to the conclusion that either frequent updates of DOM style attributes have a non-trivial negative performance impact on Android or simply the browser is optimized for fire-and-forget CSS3 transitions and it reacts a bit slower when it has to apply css property changes in rapid sequence.

 

Other than that GSAP works well in many other scenarios also on Android - and even the page translation animation is not that bad after all. But the plain CSS3 transition is smoother and more fluid.

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.
×