I was running something which does number scrolling using ScrollerJS. It supports two modes : CSS transition and DOM animation. When I was using the DOM animation mode, I find sometimes the scrolling is not smoother than that of CSS transition.
So I am wondering whether CSS transition performs better than DOM animation generally? Is there any proof or testing that shows this?
CSS transition : CSS3 transition/transform property which transforms an element
DOM animation : Traditional DOM animation which changing the CSS top property continuously.
In short, yes. Doing it in CSS allows the browser to optimize it, e.g. using hardware acceleration.
If you manipulate the DOM, the browser generally has to re-render the content, which is usually slower.
DOM manipulation is typically used to support older browsers where CSS animation is not supported (or poorly implemented).
From http://scrollerjs.pixelstech.net/#about
If CSS transition is supported in a browser, CSS transition will be
the preferred option for animation.
If in old browsers where CSS transition is not supported. DOM
animation will be chosen automatically.
However, note that as usual, things are never completely straightforward, and no generalization is completely true... There are javascript animation libraries out there that can rival or sometimes even outperform CSS-based transitions/animations, and they are usually more flexible. Here's some light reading:
http://davidwalsh.name/css-js-animation
https://css-tricks.com/myth-busting-css-animations-vs-javascript/
This question isn't too hard to answer.
A DOM animation uses your CPU for it's calculations and since an animation is quite heavy on the CPU it'll sometimes 'lag' which is when you see artefacts on the screen.
CSS3 transitions however are able to use hardware acceleration which uses the GPU of your computer (if it has one ofc :D). Since your GPU is much stronger and better at doing things like animating, you'll barely notice any lag if any.
This question is not easy to answer because in different cases some kind of animation performs better than the other.
I think this article could be more than interesting if we are talking (seriously) about performance between CSS and DOM animations.
If you are going to work a lot with animations and you are worry about the performance I suggest to try a more professional library like GSAP, they also have a scroll plugin.
Related
When using scaling to change the size of an HTML element containing text, the text jitters during the animation, but only if being animated with JavaScript libraries.
The jittering is most visible when the animation is slower and the text is smaller. I can't seem to figure out what causes it or how to get rid of it.
This jittering does not occur during CSS animations or animations using the fairly new JavaScript Web Animations API. It also doesn't seem to occur in some browsers. (On my iPhone)
To easily compare the different methods of animating the scaling of an element and how they appear, I made a CodePen for convenience. Before checking it out, note these points:
All the animations are using some form or imitation of the CSS property transform: scale(num); for the animation and have the same easing and duration so they can be compared more easily.
Although the jittering appears on macOS too, it is almost impossible to see on Macs with retina screens because of the high resolution.
The results I got are a reflection of the appearance of the animations on a Windows 10 machine in Google Chrome 59, although for me Microsoft Edge also showed the same results.
So my question is this: How can I prevent the text from jittering or becoming blurry when animating a scale property with JavaScript? How can I make the text in my JavaScript scale animations appear just as smooth as they do when using CSS?
You may be wondering why I don't just use CSS. The answer is because I'm frustrated with how limited CSS animation is. I would like to use advanced easing functions beyond the capabilities of a simple bezier curve (like Robert Penner's bounce and elastic functions), and use different easings on hover when the mouse enters and exits the element. This s completely my own opinion, but so far the only painless way I've found to do this is with JavaScript libraries. Besides their functionality relating to easing, most seem to offer many other capabilities which make animating much more effortless. If you know of a better way to get all the functionality I need please let me know!
What you are encountering are differences in a browser's layerizing strategy. You'll find that all the examples appear smooth in Firefox. That's because Firefox detects when script is changing a property that can animated using layers and creates a layer in response.
Although all browsers create layers when needed for declarative animations (CSS animations, CSS transitions, Web Animations API animations, and even SVG SMIL animations in some cases) not all browsers do it for Javascript animations. So, for those browsers you need to try to trick the browser into creating a layer (or, you could just file a bug on the browser, since it really should do this for you!).
Until recently, using will-change: transform was the recommended approach to get a browser to create a layer. However, Chrome changed its rendering strategy and now will-change: transform can produce very blurry results with scale animations in Chrome. Some people have succeeded in tricking Chrome to layerize at a higher resolution initially and then scaling their element down before animating. This is really unfortunate to have to do this and I can only encourage you to petition Chrome to fix this.
Also, the examples using "with HA" are not accurate. The CSS animation in (1) will also use hardware acceleration in every browser I know of--there's no need to add perspective in. Unfortunately, there is a lot of misleading information in this area (e.g. some articles claim animations can run on the GPU but that's simply not true). At the risk of self promotion, you might find an article I wrote on this last year helpful.
For example, if the swipe is slower, transition speed should also slow down.
If this is not possible with only CSS, what would be the least painful way to approach this with javascript? Essentially I'm trying to avoid declaring the transition rules in javascript.
You could stablish the rules for the transition in CSS (transition-property, transition-delay and transition-timing-function), and use javascript just to set transition-duration. This way everything is set up in CSS except the duration, which is what you want.
In short:
Why is this:
$('body').animate({scrollLeft: 1000});
much much faster than this:
$('body').animate({"margin-left": 1000});
?
Background:
I am working on a website that has a animated scrolling. e.g.: When the user clicks a link I fire a javascript that animates the scrollbar. Something similar to this website:
http://www.fashionphotographer.it/
My first take on this problem was to animate the margin-left using jQuery.animate but this proved to be very slow (my site is very content heavy). After that I tried animating the left of a absolute element, using CSS3 and even the -webkit-transform. All solutions where slow.
My last try was to use jQuery to animate the scrollbar, and this proved to be best solution so far.
My question is: What kind of optimization is the browser (I am using Chrome) doing under the hood that makes animating the scrollbar the best solution?
Changing the scrollLeft property will not force a reflow of the DOM, as you are really just changing which portion of the content is visible at any one time. margin-left, left or other smiliar properties, on the other hand, may cause other elements to resize, which forces the browser to reflow the DOM.
Edit: I believe scrollLeft will force a repaint, however this is much less intensive than a reflow. See http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/ for a good explanation of the difference.
As I understand hardware acceleration on iOS devices is enabled when using translate3d(). So why this test on jsperf shows that using css left/top is faster?
I have used translate3d extensively on iOS in lieu of CSS left/top, and I can say one thing:
It is truly faster for animating things (which jsperf does not seem to do.) My guess is, left/top is faster when benchmarking since nothing is animated and I don't think anything is displayed either.
It is when used in conjunction with transition (or -webkit-transition) that translate3d works its magic.
Often times in applications I have a property that would normally .animate(), but every now and then must change instantly. Usually I just set the speed to 0 when doing this, but in an application I'm developing now, my situation is the opposite and performance is much more important. This property is set with .css() on window .resize(), which fires very rapidly (in good browsers anyway), but I'll need to animate this transition sometimes. I'm wondering if it's worth it to use a conditional to set the property with .css() when appropriate and animate when appropriate—or—if .animate() doesn't have much more overhead when the speed is set to 0, I can just do that and save a few lines of code.
There isn't a ton of overhead there, but a more performant option to leaving in your animates and setting new styles instantly is to toggle animations on or off.
http://docs.jquery.com/Effects/jQuery.fx.off
That should detail how to switch animations on or off. If animations are off, then it short circuits most of the overhead of the animate function and just applies the new css.