Have you ever noticed apps stuttering as you scroll and swipe around? Tapped a button and watched the entire interface freeze as it tries to react? iOS is well-known for its user experience quality bar, but meeting that bar can be difficult, especially on older iPhones and iPads. Polished apps typically use piecemeal performance optimizations to keep their interfaces fluid, treating different sources of slowness as different problems. Today we’re open-sourcing AsyncDisplayKit, a framework that offers a holistic way to keep your app smooth and responsive.
The case for AsyncDisplayKit
iOS user interface functionality — drawing to the screen, responding to touch events, running physics simulations for inertial scrolling, and so on — is bottlenecked by the main thread. For an app to maintain the gold standard of 60 frames per second, it can only use the main thread for milliseconds at a time. But main-thread-only UIKit views like UIImageView and UITextView can take tens to hundreds of milliseconds to size and display themselves. And while the main thread is decoding an image or rendering text, it can’t respond to user input or keep up with scrolling.
Since using stock UIKit views can cause slowdowns, performant apps tend to have workarounds for individual UIKit components. Instead of letting UIImageView do expensive work itself, they might manually use Core Graphics to decompress JPEGs and PNGs in the background; instead of using UITextView, they might work with Core Text directly. This approach is effective, but has limitations — individual workarounds tend to behave differently, making it difficult to reason about higher-level improvements and application behavior.
AsyncDisplayKit builds on UIKit and Core Animation to offer a general solution. Its image and text views can be used without blocking the main thread, offering a drop-in solution for this common task. More importantly, it supports asynchronously creating and rendering complex view hierarchies the same way.
Introducing the node
The AsyncDisplayKit node is a thread-safe abstraction over UIView, which is in turn an abstraction over CALayer:
If you know how to use views, you know how to use nodes. ASImageNode and the Text Kit-powered ASTextNode can be used just like their UIKit counterparts. Unlike UIKit view hierarchies, node hierarchies for entire screenfuls of content can be initialized and laid out on background threads — and nodes make it easy to take advantage of the multicore CPUs in all current iOS devices.
Nodes have many advantages over views. For example, you can often improve performance by replacing views with layers. Unfortunately, doing so requires the tedious process of porting view-based code to the different API and inevitably risks regressions. With nodes, it’s as easy as:
If you later need to switch from layers back to views, it’s a one-line change! This is a transformational difference. Instead of being cautious of layer-backed UI code, you can use it by default whenever you don’t need touch handling.
Getting started
AsyncDisplayKit is robust and ready for use in your apps. We originally built it to make Paper’s highly tactile user interface possible, and it goes hand-in-hand with the Pop animation engine, but it’s just as powerful with UIKit Dynamics and conventional app designs. We can’t wait to see what you’ll create with it.
Check out the guide or the NSLondon talk to learn more. AsyncDisplayKit is available on GitHub.