Using AsyncDisplayKit for a smooth UI

27. March 2016 blog 0

So we’re building this awesome new app but after spending time revamping our result list we found out it just wasn’t performing well enough. We were using a UICollectionView but calculating the position of all the elements in each item in the collection was just too slow. We found out about AsyncDisplayKit (ASDK).

ASDK offers an abstraction over UIView and CALayer that allows you to perform the calculation of frames to background threads instead of the main thread. This dramatically speeds up the rendering of complex UI’s. After implementing ASDK our list is now super smooth and doesn’t lag at all.

Here are some things to take into consideration when implementing ASDK:

  • Actively maintained. The ASDK library is under very active development. It was originally built to power facebook’s Paper app and it seems mature enough to use in live projects.
  • Objective-C, not Swift. ASDK is built in Objective-C. It’s not complicated to use an Objective-C library in a Swift project but if you’re a Swift purist you might not want to do this.
  • Nodes, not Views. ASDK uses a concept called “Nodes”. Nodes are essentially UI elements and can be considered an abstraction of a View or a Layer. You use these nodes to define your UI and ASDK will asynchronously create views or layers to represent this UI.
  • LayoutSpec, not Auto Layout. Because ASDK uses Nodes to define UI elements, it doesn’t support things like Auto Layout or Constraints. Instead, ASDK uses something called a “LayoutSpec”. There are a number of different ways to layout nodes. To get an idea of the kind of layout you can define, have a look at the *LayoutSpec Class References.

 

Example node

Here’s an example of a very simple custom ASDK node. All this node does is display a label (called an “ASTextNode” within the bounds of the node. The LayoutSpec for this node also defines an inset of 10 pixels all around the text node.

 

Other resources


The path to smooth scrolling UICollectionViews

03. March 2016 blog 0

We have a pretty standard app. It’s a list of items and if you click one of these items, you go to a detail page. This kind of list / detail paradigms are used very often. For instance in mail apps, note apps etc. It is not difficult to build such an app, but it is difficult to build such an app well. Once you start making a more complex UI you often run into performance issues. We found ourselves in such a situation last week.

UICollectionView

The list of houses we implemented in the funda app is backed by a UICollectionView. A UICollectionView is a a very flexible way of building a list because the size and layout of the items in the list can be customised. This allows us to build a simple vertical list at first but morph it into a grid once we convert our iPhone-only app to an iPad format. Unfortunately this flexibility comes at a price. Having dynamically sized cells and rich content within these cells is very expensive. Every time a cell is configured with the content of a house we make new labels, download a new image and place all these elements at their correct location. Most of these actions are done on the main thread by default and thus slow down or halt the actual scrolling of the list. Additionally, we used Auto Layout to layout all the elements in the cell and this was certainly not helping our performance either.

Enter ASyncDisplayKit

While searching for a solution for this performance issue I ran across AsyncDisplayKit. This library made by facebook makes it possible to construct and layout views (they call it “nodes”) in a background thread. By doing all the heavy lifting in the background, the main thread of the app remains responsive and the list scrolls very smoothly.

So that’s where we are right now. I made an initial attempt to integrate ASDK in our current architecture but it proved to be quite tricky. Since our collection cells have a dynamic height there