Skip to content

Instantly share code, notes, and snippets.

@petehunt
Created November 23, 2013 18:42
Show Gist options
  • Save petehunt/7618353 to your computer and use it in GitHub Desktop.
Save petehunt/7618353 to your computer and use it in GitHub Desktop.
First of all, I have an experimental branch with React that lets you use compile CSS animations just-in-time with our reconciliation system and use those instead of pure JS. So I recognize that they should be supported.
In my experience CSS transitions and animations work fine for things that will always animate fully and will never have the animation changed. A good example is a fade out when deleting a list item.
I've just found that in my own work most animations are tied with direct user touch manipulation (like animating out the left nav w/ parallax and opacity) which requires frame-by-frame responsiveness to touch events and inertia calculations based on the user's touch velocity. It's impossible to do this without doing frame-by-frame.
Your skepticism is definitely warranted and I complain to browser vendors whenever I see them about this. In my experience, modern (1 year old) phones can do this with minimal jank but there can still be issues. Assuming you're already avoiding reflows, here are the three main sources of jank:
1. Image decoding
This one is a *killer*. Whenever you load in an image it blocks the UI thread as it is decoded and painted and there's nothing you can do about it. I got around it by building a web worker JPEG image decoder and then incrementally painting to a canvas, but it was really slow. Once the decoded images are cached in texture memory they're fast, but there's a limited about of texture memory so you can't load too many images. Please complain to your local browser vendor about this.
2. Garbage collection
This one is overrated. I have seen dropped frames from it but if you're somewhat careful about object allocations it's not so bad.
3. Doing too much stuff in JS
Most JS apps aren't doing too much -- they're basically updating a few data models based on user behavior and hitting the server. In case your JS app is doing more you could use a web worker to offload this work.
My example has a component called StaticContainer which will block updates to all components that aren't currently animating. This is a great feature of React since it'll prevent you from accidentally messing up the animation if you need to do more work in a child component. That is: imagine you were doing crazy expensive computation in the frosted glass content page. During the animation React would pause that work until the animation completes.
@MaKleSoft
Copy link

One thing were I found the non-blocking nature of CSS animations extremely useful are view transitions. A problem I often faced when developing single-page web apps for mobile was the fact that rendering complex views would often cause noticeable delays and jank in view transitions. In the Chuisy app I solved this problem by deferring most of the rendering and view setup to after the view transition has started, giving the user a much snappier and smoother experience. I even wrote a guest post in the Enyo blog about this (http://blog.enyojs.com/post/59808390368/ultra-fast-view-transitions-using-enyo). I also talk about how frame-by-frame JS animations are evil and should be avoided at all costs ;)

Of course your point about animations often being tied to touch manipulation is valid, but I found that often you can actually quite seamlessly combine direct touch manipulation with CSS transitions. Hell, the Enyo team even managed to pull off a scroll strategy that uses CSS transitions to simulate scroll inertia! https://github.com/enyojs/enyo/blob/master/source/touch/TransitionScrollStrategy.js

@petehunt
Copy link
Author

Cool. If you didn't observe much of a delay when starting the transition or animation I may need to explore this strategy :) I do believe it's how iscroll works. The original point of the demo was to show off how fast react's render system was so css animations would have been considered cheating :)

@MaKleSoft
Copy link

The Chuisy app uses that scroll strategy in case you want a demonstration. Not sure how well it works outside of iOS though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment