I recently had an interesting Twitter exchange with Joe Hewitt on our (as in Zynga) newly released Scroller that is somewhat in direct competition with his excellent Scrollability plugin. Both share at least one similar ambition: To give us native-feel iOS panning wherever we want it. Joe even recently blogged about how to do fast animations on iOS.
He was spot on during our Twitter exchange – his Scrollability demo performed amazingly well, while our own Scroller demo sucked hard on an iPhone 4 with iOS 4 (it was ok on iPad). Joe suggested that one has to use CSS Animations or transitions to improve framerates. He also suggested to use the “scale” transform to handle content scaling. Being an early adopter of CSS Transforms and all things shiny myself, I had my doubts about the JS animation vs. keyframe animation part. My own tests on sprite animations suggested that in fact, CSS keyframe animations were not at all faster than JS animations. In addition to that, even if there was a speed increase, there are multiple issues with implementing it that way:
- Scroller is designed with portability in mind. It only handles logic, and does not apply values. It can therefore be used in any environment, including Canvas.
- Zooming isn’t as easy as just putting a “scale” transform on the content and be happy. CSS Transforms do not modify the bounding box, so the content doesn’t actually become bigger. You won’t be able to pan to the edges anymore.
That being said, I was still curious on why our demo performed so bad in contrast to Scrollability’s shining examples. So I went ahead and created a couple quick mashup demos to be able to compare the context as well as functionality. First, I took Joe’s table demo, removed Scrollability and put our Scroller on it. No content or logic changes. Compare:
Holy crap! Now that both are running in the same demo and scenario, performance on both is amazingly similar on an iPhone 4 running iOS 4. Scrollability still feels a tick smoother, but both are very usable and nice. I wasn’t finished yet so I created another interesting test case, putting Scrollability into our own DOM demo. In order to be able to compare, I deactivated zooming and horizontal scrolling on both. Here are the results:
This is pretty amazing. On my iPhone 4, I found Scroller outperform Scrollability by a quite visible margin, and the margin is even greater on Chrome for Mac. At this point, I don’t have a clue as to why Scroller performs better – one possible reason might be the missing scroll indicator.
I have heard from a couple people that they couldn’t confirm Scroller being faster than Scrollability on iPhone 4. After hours of debugging, I finally found out why they saw so different results. If you have the debug console in mobile Safari enabled, Scroller will always outperform Scrollability. If you have it disabled, Scrollability will outperform Scroller by a great margin. It’s completely mysterious, and it doesn’t help that Apple doesn’t give us debug info. I will continue to investigate what the issues are and update this blog post. Stay tuned.
Update 2: Obviously it had to be something silly. It wasn’t the viewport size. It wasn’t even the Scroller. It was the logging of debug values into input fields that caused a dramatic slowdown in Scroller when the debug console was not activated. I still have no clue why it was fast with debug on, but the riddle is solved. Scroller now always outperforms Scrollability.
In the end, I have learned that it’s not only the code itself that makes things fast, but the context. Only by comparing against the same context, the same markup in our demos, I was able to realistically learn about performance impacts. But as with all comparisons, take it with a good grain of salt. While Scroller and Scrollability have overlapping featuresets, there’s things that are different: Scrollability has a scroll indicator while Scroller doesn’t (it’s all logic, really), and Scroller additionally comes with zooming, both directions scrolling and some more.
And both have their respective use cases: I found it amazing how simple it was to setup Scrollability – it’s a great and easy plugin if you need simple scrolling content. For advanced scenarios such as games or more interactive content on Canvas or WebGL, I encourage you to try the Scroller. It requires more setup, but comes with greater flexiblity.
Until next time!