I am building a slideshow, and I'd like to include smooth (subpixel) image transitions involving sliding and resizing, like for example a Ken Burns effect.
I see that people use various techniques. I'd be interested to know which ones are considered the best approach today, and if any of these are just urban myths that actually bring no improvement:
css transitions
JavaScript requireanimationframe
image embedded in a canvas element
other?
Note: I undertand that some of these techniques are not supported in older browsers. My question is for thwe most recent versions (IE9, Firefox 5, etc.).
I think CSS transitions could be a good answer to the major parts of the effects you want.
CSS transitions are designed for changing smoothly between two states of an element.
For ken burns effect It could be accomplish by doing transitions of width on two pictures that are on absolute position for example.
Using Javascript to animate can be a bit laborious and if you want to manipulate dom on each frame it can be heavy for performance.
I also think canvas is not the best solutions because canvas element is not dynamically scalable without problem (performance particulary).
See the following post on Javascript Performance Optimizations:
It outlines different performance techniques across 5 broad subjects:
Avoiding interaction with host objects (DOM)
Managing and Actively reducing your Dependencies
Disciplined event binding
Maximising the efficiency of your iterations
Becoming friends with the JavaScript lexicon
The ones that apply the most to smooth image transitions are in sections 1, 3 and 4, particularly the use of pointer references to browser DOM objects (so you dont have to traverse the DOM multiple times), applying DOM changes in batches, and optimizing the efficiency of your iterations.
However all 5 sections are useful for creating a highly responsive UI
Related
I'm working on an iPad HTML5 app and I've already implemented ontouch support to trigger events faster and I'm using jQuery to target the elements easier, but for the animations I'm using CSS3 transitions
What do you think is faster? using jQuery animations since I already have imported the library or use CSS3 transitions when targeting elements with jQuery?
According to this link, jQuery animation is much slower then css animation.
Reason can be because jquery has to modify the props of the DOM element using timers and a loop. The CSS is part of the browser engine . which depends pretty much on hardware of system. You can also check that in profiling of Chrome or Firefox.
CSS animations will almost always be faster.
A head to head comparison of CSS transitions and jQuery's animate.
Rather than setting a timer to run repeatedly, transitions are handled
natively by the browser. In my rather unscientific testing,
transitions are always quicker, running with a higher frame rate,
especially with high numbers of elements. They also have the advantage
that colours can be animated easily, rather than having to rely on
plugins.
http://css.dzone.com/articles/css3-transitions-vs-jquery
Related Question:
Performance of CSS Transitions vs. JS animation packages
CSS3 Transitions should be faster because they are native to the browser.
Its css3 its faster and consumes lesser memory and is smoother.
CSS processor is written in C++ and native code executes very fast whereas jQuery (JavaScript) is an interpreted language and the browser can't predict JavaScript ahead in time.
http://dev.opera.com/articles/view/css3-vs-jquery-animations/
View the above link to know about the experiments held over CSS3 vs jQuery
This article (http://css-tricks.com/myth-busting-css-animations-vs-javascript/) does an excellent comparison of CSS transforms vs. jQuery animations vs. GSAP (another JavaScript library).
CSS animations are significantly faster than jQuery. However, on most devices and browsers I tested, the JavaScript-based GSAP performed even better than CSS animations
So CSS transforms are faster than jQuery animations, but don't let this make you assume that CSS transforms are faster than JavaScript. GSAP shows that JavaScript can outperform CSS.
CSS3 will be faster as it comes standard with the browser where as JQuery is another file that has to be loaded, however I have found that depending on the animation that JQuery can run a lot smoother. Sometimes it's also nice to experiment with pure Javascript now and again.
The Mozilla developer documentation raises some interesting points regarding CSS3 animation:
Letting the browser control the animation sequence lets the browser
optimize performance and efficiency by, for example, reducing the
update frequency of animations running in tabs that aren't currently
visible.
WebKit (which powered Safari) also makes use of hardware accelerated compositing, which can have a much greater effect on performance than anything Javascript can do at this time. (I think this will change very soon though as more functions are added to manage calculations) This is because it will take advantage of dedicated hardware if it available to perform the calculations, rather than making it happen through a translated language like Javascript.
I am not 100% certain whether WebKit on the iPad is hardware accelerated; however it would stand to reason that because it is standardized and increasing in popularity, that this would only improve with time.
From here
A head to head comparison of CSS transitions and jQuery's animate.
Rather than setting a timer to run repeatedly, transitions are handled natively
by the browser.
In my rather unscientific testing, transitions are always quicker, running with a
higher frame rate, especially with high numbers of elements. They also have the
advantage that colours can be animated easily, rather than having to rely on
plugins.
A test here along with this conclusion.
Javascript animations based on timers can never be as quick as native
animations,
as they don't have access to enough of browser to make the same optimisations.
These animations should be used as a fallback only in legacy browsers.
Also notice this,
CSS3 animations are terriffic but do use a lot of your processor’s
power.
There is no way to fine tune the animation with CSS3 the same way you can using a
framework like jQuery. So, as long as CSS3 animations aren’t CPU friendly you
better stick with jQuery.
If you're using jQuery/javascript animation with the canvas tag (which if I'm not mistaken still relies upon a timer... new to playing around with it though), then it gives you the advantage of hardware acceleration with javascript. If you're just looking to move something around when you hover then transitions work great. CSS transitions may run a little smoother but it's a trade off, you're relinquishing a ton of javascript control over the animation by using transitions. I like to keep style in CSS and behavior in JS - isn't that how it's supposed to work anyway? CSS transitions kind of broke that logic...
Native is supposed to be faster, but if browser developers are sloppy (or lazy), they write bad code, which leads to poor results with CSS animations (or transitions).
Nowadays, jQuery has a plugin which overides the "animation" function with an "improved" one. see Velocity. I'm not getting into other ways to animate the DOM with javascript because it's outside the scope of this question.
So, as-is, jQuery is slower than CSS. also, CSS is easier to write because you already have the element style probably, so adding a few rules is easy, compared to a situation where you need to start writing JS somewhere and manage it..but for complex, heavy stuff, JS is faster, sadly.
A very good article about this exact question - http://davidwalsh.name/css-js-animation
A very common question, but almost all comparison I've seen is mainly focused on games with a lot of interaction.
What I'll be working on is a web application that manipulate objects one at a time. For example, the object can be either an image or a text, then it can be replaced, resized, rotated, zoomed in, and deleted.
If the manipulations applied to many objects, I know that canvas will be a better choice but here the manipulation only can be done one at a time to one object only. Each container will at most have about 30 object in it, and I'll be working on multiple containers (maybe around 20 containers) that will be hidden or shown depends on the interaction.
The question is whether to use Canvas or CSS3? What I'm looking is the performance issue and complexity of the app.
I don't have a lot of experience with canvas but as far as I know if you use it together with requestAnimationFrame the performance is pretty similar to CSS animations. You should also consider that CSS animations are very limited when it comes to working with complex animations.
If I have multiple (up to a dozen perhaps) images for which I want to do things like change position, resize, fade in and out, and rotate, I figure my options are Flash (which I don't really want to use), <canvas>, or lots of <img> tags and jQuery.
I'm sure it depends on a lot of factors - the browser and its layout engine, for one - but I'm wondering if it's possible to generalize that one of these methods is likely to be faster than the other.
I'm not so interested in browser compatibility - this is for an art project - so speed is really what I'm concerned about, because I have seen jQuery animations get choppy before and I want to avoid that.
If you can require a modern browser, then for best performance use CSS3 transitions.
These will offload to the GPU where possible, and will let the browser handle fades, rotations, etc, all completely autonomously.
Use jQuery if you need to just to trigger actions.
As you said, it depends on the browser.
The js/jQuery way will work for every browser except for rotations.
HTML5 Canvas won't work on old browsers for example IE 6, 7, 8 (see http://caniuse.com/#feat=canvas).
Flash won't probably work on most mobiles and it will need to be downloaded.
I am in process of making a game where the health bar (animated) and some other info represented visually like some icons showing the number of bombs the player has etc. Now, this can be done both in canvas (by making another canvas for info that sits over the main canvas, or it can be done using many divs and spans with absolute positioning. This is my first time in making a browser based game so if any experienced people view this, tell me what you recommend. I would like to know that which method would be faster.
The game will also be running on mobile devices. Thanks!
There is no straighforward answer and I suggest you do FPS testing with different browser how it plays out for your use case. If you do not wish to go such in-depth I suggest you simply draw the elements inside canvas and if you need to hide them then leave out drawHUD() call from your rendering loop.
For HTML HUD overlay on <canvas> the following factors should be considered
Can the web browser compositor do hardware accelerated <canvas> properly if there are DOM elements upon the canvas
HTML / DOM manipulation will be always slower than <canvas> operations due to inherited complexity dealing with DOM elements
<canvas> pixel space stays inside <canvas> and it might be difficult to have pixel-perfect aligment if you try to draw elements on <canvas> outside the canvas itself
HTML offers much more formatting options for text than canvas drawString() - is HTML formatting necessary
Use the canvas. Use two canvases if you want, one overlaid over the other, but use the canvas.
Touching the DOM at all is slow. Making the document redo its layout because the size of DOM elements moved is very slow. Dealing with the canceling (or not) of even more events because there are DOM items physically on top of the canvas can be a pain and why bother dealing with that?
If your HUD does not update very often then the fastest thing to do would be drawing it to an in-memory canvas when it changes, and then always drawing that canvas to the main canvas when you update the frame. In that way your drawHud method will look exactly like this:
function drawHUD() {
// This is what gets called every frame
// one call to drawImage = simple and fast
ctx.drawImage(inMemoryCanvas, 0, 0);
}
and of course updating the HUD information would be like:
function updateHUD() {
// This is only called if information in the HUD changes
inMemCtx.clearRect(0, 0, width, height);
inMemCtx.fillRect(blah);
inMemCtx.drawImage(SomeHudImage, x, y);
var textToDraw = "Actually text is really slow and if there's" +
"often repeated lines of text in your game you should be" +
"caching them to images instead";
inMemCtx.fillText(textToDraw, x, y);
}
Since HUDs often contain text I really do urge caching it if you're using any. More on text performance here.
As others have said, there is no universally best approach, as it depends on the specifics of what you need to render, how often, and possibly what messaging needs to happen between graphical components.
While it is true the DOM reflows are expensive, this blanket warning is not always applicable. For instance, using position:fixed; elements avoids triggering reflows for the page (not necessarily within the element if there are non-fixed children). Repaint is (correct me if this is wrong) expensive because it is pixel pushing, and so is not intrinsically slower than pushing the same number of pixels to a canvas. It can be faster for some things. What's more, each has certain operations that have performance advantages over the other.
Here are some points to consider:
It's increasingly possible to use WebGL-accelerated canvas elements on many A-grade browsers. This works fine for 2D, with the advantage that drawing operations are sent to the GPU, which is MUCH faster than the 2D context. However this may not be available on some target platforms (e.g., at the time of this writing, it is available in iOS Safari but not in the iOS UIWebView used if you target hybrid mobile applications.) Using a library to wrap canvas can abstract this and use WebGL if its available. Take a look at pixi.js.
Conversely, the DOM has CSS3 animations/transitions which are typically hardware-accelerated by the GPU automatically (with no reliance on WebGL). Depending on the type of animation, you can often get much faster results this way than with canvas, and often with simpler code.
Ultimately, as a rule in software performance, understanding the algorithms used is critical. That is, regardless of which approach used, how are you scheduling animation frames? Have you looked in a profiler to see what things take the most time? This practice is excellent for understanding what is impacting performance.
I've been working on an app with multiple animations, and have implemented each component both as DOM and canvas. I was initially surprised that the DOM version was higher performant than the canvas (wrapped with KineticJS) version, though I know see that this was because all the animated elements were position:fixed and using CSS (under the hood via jQuery UI), thereby getting GPU performance. However the code to manage these elements felt clunky (in my case, ymmv). Using a canvas approach allows more pixel-perfect rendering, but then it loses the ability to style with CSS (which technically allows pixel-perfect rendering as well but may be more or less complex to achieve).
I achieved a big speed up by throttling the most complex animation to a lower framerate, which for my case is indistinguishable from the 60fps version but runs smooth as butter on an older iPad 2. Throttling required using requestAnimationFrame and clamping calls to be no more often than the desired framerate. This would be hard to do with CSS animations on the DOM (though again, these are intrinsically faster for many things). The next thing I'm looking at is syncing multiple canvas-based components to the same requestAnimationFrame loop (possibly independently throttled, or a round-robin approach where each component gets a set fraction of the framerate, which may work okay for 2-3 elements. (Incidentally, I have some GUI controls like sliders that are not locked to any framerate as they are should be as close to 60fps as possible and are small/simple enough that I haven't seen performance issues with them).
I also achieved a huge speed boost by profiling and seeing that one class in my code that had nothing to do with the GUI was having a specific method called very often to calculate a property. The class in question was immutable, so I changed the method to memoize the value and saw the CPU usage drop in half. Thanks Chrome DevTools and the flame chart! Always profile.
Most of the time, the number of pixels being updated will tend to be the biggest bottleneck, though if you can do it on the GPU you have effectively regained all the CPU for your code. DOM reflows should be avoided, but this does not mean avoid the DOM. Some elements are far simpler to render using the DOM (e.g. text!) and may be optimized by the browser's (or OS's) native code more than canvas. Finally, if you can get acceptable performance for a given component using either approach (DOM or canvas), use the one that makes the code simplest for managing that type of component.
Best advice is to try isolated portions in the different approaches, run with a profiler, use techniques to over-draw or otherwise push the limits to see which approach can run fastest, and do NOT optimize before you have to. The caveat to this rule is the question you are asking: how do I know in advance which technical approach is going to allow the best performance? If you pick one based on assuming the answer, you are basically prematurely optimizing and will live with the arbitrary pain this causes. If instead you are picking by rapid prototyping or (even better) controlled experiments that focus on the needs of your application, you are doing R&D :)
Browserquest displays their HUD using HTML elements, which has the benefit that you don't have to worry about redrawing etc. (and the performance will be pretty good, given that the entire browser engine is optimized to render the DOM pretty fast.
They (browserquest) also use several layered canvas elements for different game elements. I don't know the exact structure, but I guess that on which canvas an element is displayed depends on how often it needs to be redrawn.
I'm wondering is there any difference in performance of using CSS Transitions vs. any of the various JavaScript animation libraries? (script.aculo.us, scripty2, jsAnim, MooTools, $fx, etc).
I've tried various tests in Safari and Chrome but I don't actually see any difference. I thought that CSS Transitions were supposed to be hardware accelerated.
Update:
I've tried using Scriptaculous' Effect.Fade on 5 different DIVs (each containing a canvas with some lines). Doing the exact same thing using CSS transitions, I see absolutely no difference in performance. Both were very smooth with one DIV/Canvas, but both are very slow when I do more than 2 at a time.
I've tried this in Safari 4, 5 (OSX), Google Chrome 5 and FireFox 3.7pre. Same results across the board.
In answer to UpHelix's response, you're not simply limited to hover, etc. You can trigger a transition by changing any transitionable style. For instance, set the opacity of an element in JavaScript (after, you've specified the transitionPropery and transitionDuration for that element).
Yes, there is a difference, CSS is much faster. It may be difficult to see until you get many running at the same time or the more they do. CSS animations are limited though. In most cases they really only work off the :hover event. With JavaScript you can perform animations at any event: click, mouseover, mousemove, mouseout, keyup, keydown, etc.
In my opinion, jQuery is the best for JavaScript animations in 2010. See jQuery Demos
To add to Mechlar's (correct) answer: JavaScript is an interpreted language and the JS engine of the browser has to parse and execute every instruction during run-time (I know there exist JS compilers, like V8 (used in Chrome), but the principle remains the same).
On the other hand, browsers can implement CSS transitions natively, e.g. in C/C++ or something. This code will be compiled to machine language.
If CSS transitions are hardware accelerated or not, depends on the techniques the browser uses, the platform the browser runs on, etc.
You will notice the difference on mobile browsers (iPhone, Android, etc.).
CSS animations have the advantage of being processed by the browser. Fast computations and optimizations are available. In my opinion web animations performance should be looked trough a "holistic" point of view. After all an animation, in terms of FPS, can not be faster then the browser refresh.
The real performance level is given by the overall UI performance. A JS and a CSS animation can look similar. However CSS animations win since they do not block the UI thread.
Stoyan Stefanov wrote and demo how CSS animations are put out of the UI thread:
http://www.phpied.com/css-animations-off-the-ui-thread/