Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
GreenSock

Input wanted: should we change the force3D default?

Change force3D:"auto" to default in 1.14.3?  

32 members have voted

  1. 1. Should force3D:"auto" be the default in GSAP 1.14.3?

    • Yes, gimme the GPU juice, baby!
      29
    • Yes, but only for mobile devices.
      3
    • No, leave it alone please.
      0

This poll is closed to new votes


Recommended Posts

We're considering a switch to force3D:"auto" as the default in GSAP 1.14.3 because:

  1. Performance: whenever an element has a 3D transform applied (like matrix3d(...) or translate3d(...)), even when only 2D components are needed, that element gets "layerized" (put onto its own compositor/GPU layer), meaning it's much cheaper processing-wise to move/rotate/scale as long as its internals don't change (like its color or contents). Think of it like taking a photo of it and shuttling those pixels to the GPU and then just shift those around. The performance difference is particularly evident on mobile devices that have weak CPUs.
  2. More fair comparisons: We've seen some people comparing CSS animations on mobile devices with GSAP, and since those browsers "layerize" elements in CSS animations of transforms, the animations can look smoother and people assume GSAP is just slower when in reality the perceived difference is almost entirely related to the fact that CSS is layerizing things. These users often don't know that you can simply set force3D:true or force3D:"auto" in GSAP to get that layerizing and instantly see better performance especially on mobile devices. Also, we've seen some comparisons with VelocityJS that weren't fair because Velocity automatically uses 3D transforms on mobile devices, so the same sort of discrepancy was introduced. Once again, most people didn't realize they could get a speed boost in GSAP by setting force3D:"auto" which would make the comparison with Velocity more fair. 

To be clear the change would look like this in the applied CSS:

//current behavior of rotation:45:
transform: matrix(0.7071, 0.7071, -0.7071, 0.7071, 0, 0);

//behavior if force3D:"auto" was applied to rotation:45:
transform: matrix3d(0.7071, 0.7071, 0, 0, -0.7071, 0.7071, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

So what are the down sides?:

  1. There is a small performance hit when an element is first "layerized" because the browser has to take that raster image and feed it to the GPU. In most cases, this is negligible, but if you're starting a ton of tweens at the same time of hundreds or thousands of elements and they all have to get layerized, you'll see a lag at the beginning and then things will run smoothly. Most would prefer to pay the up-front cost to get smoother animation during the tween though.
  2. There's an upcoming "will-change" attribute that you'll be able to apply to elements in modern browsers that should provide the same benefits as the 3D transform "hack". So is the force3D:"auto" behavior something that will only be relevant/beneficial in the shorter term? Should we design our API in a way that directs people toward a more standards-compliant, recommended approach heading into the future? (Keep in mind that the will-change attribute is NOT applied in most browsers yet. I think only Chrome has it right now). 
  3. We've heard reports of some browsers blurring things a bit when they have a 3D transform applied, especially if you're scaling above 1. 
  4. Memory is limited on the GPU, so if you just "layerize" everything, you can run out of memory and cause things to crash or perform poorly. For example, if you're animating 2000 divs on a mobile device (doubtful), this change could cause your web page to crash whereas the old version of GSAP didn't. 
  5. Legacy code would perform differently (although things should look the same). Some people would just see an instant speed boost, but some might get a slightly blurry display because of #3 above. 
  6. Some people consider this technique a "hack" because we'd be defining a 3D transform even if only 2D is technically needed. In general, our philosophy at GreenSock has been to avoid making a lot of assumptions or stepping on the developer's toes - give them tools to get the effect they need (like force3D:"auto") but don't force it on them by default. In this case, however, the practical reality of how things work, what's common, and the tradeoffs of not doing it may trump the "hands-off" philosophy. 

If we do apply this change (which is the direction we're leaning right now), we'd provide a static property to change it so that you can easily get the old behavior back if you prefer, like:

CSSPlugin.defaultForce3D = false;

By the way force3D:"auto" means that it will only use a 3D transform DURING the tween and then revert to 2D at the end (unless the ending values require 3D of course). force3D:true would causing the transform to remain 3D even after the tween is finished. 

 

We'd love to hear what you think. Cast your vote, and feel free to comment. Any other concerns or recommendations?

  • Like 4
Link to post
Share on other sites

+1 for force3D: "auto" as default :mrgreen: , thanks for detailed explanation and the poll

  • Like 2
Link to post
Share on other sites

I say +1 for auto.

 

And about point 3 at the down side... I think it's not only GSAP that makes people think about that. Like font anti aliasing in desktop Chrome (now fixed a bit more) or flickering on mobile devices which can be fixed a bit on 3D transforms by some CSS tricks. I think it's best to make it the end user as easy as possible. 

 

For that matter, I would love some kind of attribute which simply puts a thing on top. And if it's already there, kill me ;)

Link to post
Share on other sites

I didn't know about "auto" until today. I always used true and false. What's auto do?

 

For what it's worth I have force3D: true sprinkled all over the place in my code. Almost every tween, so it would save me a lot of lines of code.

Link to post
Share on other sites

Maelfyn, force3D:"auto" means that it will only use a 3D transform DURING the tween and then revert to 2D at the end (unless the ending values require 3D of course). force3D:true would causing the transform to remain 3D even after the tween is finished. In most cases, you won't really notice much of a difference, but I prefer "auto" because it allows GPU memory to be relinquished after the tween is done. For example, if you animate 2000 <div> elements on an iPhone, force3D:true might cause the page to scroll slowly after the tweens are done just because there are so many layers that the browser has to keep in memory and render. So layerizing is a GOOD thing during the animation, but after the animation is done (if you have a LOT of layers), it's good to un-layerize it :)

 

Again, in normal situations, this isn't much of a factor. 

 

Oh, and if you keep things layerized, it can save a little time when you have to start animating the same element again because it doesn't have to go through that layerizing process again (that's all a browser thing - GSAP has no control over it except by giving it a 3D or 2D transform). 

 

Does that help?

 

And yeah, force3D:"auto" would save some typing in a lot of cases. 

  • Like 1
Link to post
Share on other sites

I am no expert, but I find myself putting force3D, translatez(0); on just about every animation these days. Browser will use the gpu by default overtime, by then you could easily remove that from the code, id hope. 

 

Awesome that you would ask our input, GSAP is amazing, thanks. 

Link to post
Share on other sites

Great input, guys. I just added an actual pole to the top - please cast your official votes there :)

Link to post
Share on other sites

Hmm, how liberally is force3D applied e.g. if I call

TweenLite.to(foo, 1, { color: "#F00" });

will foo have a transform applied to it?

Link to post
Share on other sites

Great question, Jamie. No, force3D:"auto" would ONLY get applied if/when you animate a transform-related property. 

Link to post
Share on other sites

Thanks for the great explanation. That makes a lot of sense. I am very happy to learn about that auto setting as I think I was hogging up a lot of memory with my object pooling tactics. I vote auto.

Link to post
Share on other sites

I'm all for auto but if by some chance you don't, would we be able to manually set a default? i.e. CSSPlugin.defaultForce3D = "auto"

Link to post
Share on other sites

Hello MattArtDept, Welcome to the GreenSock forum!

 

if you look at the first post above, the last part of that post, Jack wrote that you would be able to set a default:

// would set default to false
CSSPlugin.defaultForce3D = false;

// would set default to true
CSSPlugin.defaultForce3D = true;

// would set default to "auto"
CSSPlugin.defaultForce3D = "auto";

:

I hope this helps.. Happy Tweening  :)

Link to post
Share on other sites

I do not think it should be a default -- texture memory can be a precious thing. Besides, things can look bad if they were all textures. Being able to set a default for new animations, though, is a good idea.

 

I would, however, support trying to make these trigger that, because they do with plain CSS:

1) "transform: 'translate3d(0, 0, 0)'" -- without killing Greensock specific sub-transforms (or vice-versa) in the process.

2) "{x: 0, y: 0, z: 0}" -- one of these needs a small value to make the 3D texturing work...

Link to post
Share on other sites

And yeah, force3D:"auto" would save some typing in a lot of cases. 

 

+1 for anything that saves me typing.

  • Like 1
Link to post
Share on other sites

I do not think it should be a default -- texture memory can be a precious thing. Besides, things can look bad if they were all textures. Being able to set a default for new animations, though, is a good idea.

 

I would, however, support trying to make these trigger that, because they do with plain CSS:

 

1) "transform: 'translate3d(0, 0, 0)'" -- without killing Greensock specific sub-transforms (or vice-versa) in the process.

2) "{x: 0, y: 0, z: 0}" -- one of these needs a small value to make the 3D texturing work...

 

I'm not quite sure I follow this comment. Are you saying that force3D:"auto" will use up texture memory on the GPU during the animation, so you'd prefer to sacrifice [animation] performance in order to conserve texture memory? Do you feel like in 60%+ of use cases, it'll hinder things more than it will help? If so, can you explain why or provide some examples? 

 

And for your 2nd comment, are you saying that you think {transform:"translate3d(0,0,0)"} and/or {z:0} should be interpreted the same as {force3D:true}? And do you think the extra kb and slight performance hit (probably negligible) are a worthwhile tradeoff for the apparent conformity with the current CSS behavior of transform: translate3d(0,0,0)? I just want to make sure I'm understanding your points correctly before responding. 

Link to post
Share on other sites

Hey Jack, Excellent this is great to hear GSAP considering harnessing acceleration by default.

I'm slightly concerned that there are some issues with particularly chrome at the moment as you mention with

 

 

We've heard reports of some browsers blurring things a bit when they have a 3D transform applied

 

I reported it to the Chromium team ,but it's not gaining much traction at the moment. http://crbug.com/425747

 

This is a particular issue when using "retina ready" images and scaling.

There are a few workarounds suggested in my earlier thread http://greensock.com/forums/topic/10758-accelerated-scale-animations-do-not-repaint-after-tween/, so i guess not necessarily a blocker for this change.

 

Personally I'd like to see the default as "auto" to mitigate the aforementioned issue.

Link to post
Share on other sites

Hello Rob,

 

In my tests.. Most of those browser bugs (mostly seen in webkit) that blur things with 3d transforms can be fixed with either perspective on their parent or with transformPerspective applied to the element it self. Sometimes adding transform-style:preserve-3d to the element with the transform helps. Also you might have to move the values positive or negative with the z (translateZ) property to fix some blurriness as well.

 

Usually if that doesn't fix the blurriness .. than its is related to a deeper browser bug (mostly seen in webkit). In that case you just have to make your elements ending animation values be the large version with scale of 1 (you might have to adjust your elements width and height to be higher). And than scale down the element to the default size you want it to be first viewed at (a scale factor less than 1). Then when you animate or scale up the element to a scale of 1. And then you wont get the blurriness, since your element is not passing a scale factor of 1.

 

This is just my opinion from my own tests when dealing with 3D transforms. Different CSS properties can also be key in debugging blurriness issues, such as z-index, absolute positioning (top left) and so on when they are used with 3D transforms.

 

But i would love if force3D: "auto" was default! .. Since it would convert  the 3D transforms to 2D transforms if needed at its end state. Which will help when dealing with certain elements that display blurry or not at all, when 3D transforms are left on the element. For example iframes that pull video (like youtube or vimeo videos) and other HTML tags (video tag, audio tag, etc..) that do not play well when its end state has 3D transforms applied.

 

Plus i love the fact that i would have to type less, if force3D is "auto" by default.

 

Just my two cents... Happy Tweening! :)

  • Like 1
Link to post
Share on other sites

I'm not quite sure I follow this comment. Are you saying that force3D:"auto" will use up texture memory on the GPU during the animation, so you'd prefer to sacrifice [animation] performance in order to conserve texture memory? Do you feel like in 60%+ of use cases, it'll hinder things more than it will help? If so, can you explain why or provide some examples? 

 

And for your 2nd comment, are you saying that you think {transform:"translate3d(0,0,0)"} and/or {z:0} should be interpreted the same as {force3D:true}? And do you think the extra kb and slight performance hit (probably negligible) are a worthwhile tradeoff for the apparent conformity with the current CSS behavior of transform: translate3d(0,0,0)? I just want to make sure I'm understanding your points correctly before responding. 

 

Yes to all.

So yes, texture memory on phones is small compared to PCs. Combine CSS stuff with canvas webgl stuff and it gets smaller... I can't really give you any specific examples except for my game (which I'd rather not mention here right now) which can crash on lower-end phones due to low texture memory.

 

The other issue is that texture-composited sections look blurry compared to non-composited sections...

 

@Jonathan: I will see if adding perspective helps negate some blurriness...

Link to post
Share on other sites

agamemnus, I think that the scenario you're describing is an edge case and what we're talking about is what the default should be, and in my opinion the most important factor in determining that is to look at which setting is the most beneficial for the most people. From what I've seen out in the wild, the VAST majority of use cases wouldn't run into some sort of texture memory shortage, and they'd perform noticeably better with force3D:"auto". If someone starts running into a GPU memory issue, they always have the option of setting force3D:false to remedy that. In other words, GSAP still delivers ultimate flexibility, but we want to make the default "out of the box" behavior as fast as possible for the most people. 

 

The blurring issue is certainly valid, but again it seems like an edge case that could be resolved with force3D:false if necessary (or use one of the fixes Jonathan mentioned). 

 

Agreed? 

  • Like 2
Link to post
Share on other sites

I say we should do it. I just saw the results, 99% of votes actually are for the default setting of force3D: auto.

 

If this significantly increases speed then why not? It would also throw aside some misconceptions about velocity being faster. Velocity is trying to apply makeup to some old dinosaur (Jquery).  Just give everyone the final blow and apply the new standard setting. It is time to end the era of jquery plugins : )

Link to post
Share on other sites

Curious but is there a good way to monitor that memory use and what normal mobile devices have to spend? And it's not a problem for me, I'm from the old days where they want a page to be no more as 30kB. So I try to do a lot to optimize things. With the site I'm working on I test a lot on my iPad 2 (the old one) but I don't have a clue what other devices do. Think it would be nice to have some kind of chart in the docs about performance and specs. Or a kind of cheat chart for certain devices. And it's not that I make such complicated things but sometimes I read something in this forum about certain devices and their problems with some kind of tweens. Would be nice to have some kind of overview.

Link to post
Share on other sites

Putting aside the developer desires (which I appreciate a lot that you are canvasing our opinions), on a purely commercial basis I think you don't have a choice but set force3d as default. Maybe to the few here that really delve down the rabbit hole of coding, will understand the difference, but if a larger less informed group only see simple unqualified results, that one is faster than another, then that hurts.

 

As I think previous posters have mentioned, chrome sometimes plays funny tricks with 3d transform when added programmatically, that break the static setup.

 

e.g if I recall, chrome has a bug that breaks positioning and or z-index if you later add 3d transforms, although in most cases it want be encountered.

Link to post
Share on other sites

Hello nastid, and Welcome to the GreenSock Forum!

 

I dont see this affecting users like you describe since each animation is different. I believe having force3D auto, helps not only in writing less code but helps in a wide array of browser bugs. For example, regarding the z-index and 3D transform bug. This happens because of the z-axis in the 3d transform giving the element a new stacking order. By using force3D:"auto" for 3d transforms you ensure the transform is converted to a 2D tween after the tween renders (if a transform is needed at its end state), so you dont have your tweens affected by this WebKit bug regarding z-index and 3d transforms (especially the z-axis).

 

You could also get around the z-index and 3d transform bug, by either having translate3d(0,0,0) or translateZ(0) on those elements that are positioned with absolute or relative (basically the elements that have z-index)

 

By having force3D:"auto", it will fix a lot of browser bugs right out the gate. But of course if you a dealing with over a 100 tweens. Then you can make the choice depending on your animation if you need force3D auto, and if you dont, you can set either true or false for a new force3D default.

 

Happy Tweening!

Link to post
Share on other sites

Wait, sorry I meant didn't have a choice but set it to auto, I left the last bit out  :)

 

And yes completely agree. That's why I said in most cases the bug(s) wont be encountered, and have used those work-arounds too!

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

    No registered users viewing this page.

×