A Fast View Layout Library for iOS Applications
June 28, 2016
Fast performance is a key feature of LinkedIn’s mobile applications. So when we first released the new LinkedIn iOS app, and we learned that our members were experiencing noticeable delays when viewing certain profiles, we immediately investigated the issue to find a solution.
Performance profiling revealed that the main thread was spending a significant amount of time running Auto Layout. Auto Layout is a layout engine provided by iOS that dynamically calculates the size and position of views on the screen by solving a system of constraints.
It was difficult for us to identify exactly why Auto Layout did not perform well in certain cases because there was no useful information in the performance profile. We also didn’t have access to Auto Layout’s implementation, since it is not open sourced. Fortunately, we were able to improve the performance of the profile page by experimenting with different sets of constraints and by fixing a few places in our code where we weren’t following best practices. Unfortunately, the resulting performance was still not acceptable, and we needed an alternative solution.
Our implementation of the LinkedIn news feed taught us that we could achieve maximum performance by manually writing layout code, but we had also learned that manual layout code can be difficult to maintain. We knew that an ideal solution would encapsulate the layout calculations into reusable components while maintaining good performance.
LinkedIn is not the first company to encounter performance problems with Auto Layout, so we searched for an open source alternative that met our requirements:
- It needed to be fast (on par with manual layout).
- It needed to support Swift because we use it extensively at LinkedIn.
- It needed to be maintained and have non-trivial adoption (reliability and stability).
- It needed to have an acceptable license.
We were not able to find a project that had all of the features we were looking for, so we built LayoutKit.
LayoutKit is a declarative view layout library for iOS applications that has many benefits over using Auto Layout:
- Fast: LayoutKit is as fast as manual layout code and significantly faster than Auto Layout.
- Asynchronous: Layouts can be computed in a background thread so user interactions are not interrupted.
- Declarative: Layouts are declared with immutable data structures. This makes layout code easier to develop, code review, debug, and maintain.
- Cacheable: Layout results are immutable data structures so they can be precomputed in the background and cached to increase user perceived performance.
LayoutKit also provides benefits that make it as easy to use as Auto Layout:
- UIKit friendly: LayoutKit produces UIViews and also provides an adapter that makes it easy to use with UITableView and UICollectionView.
- Internationalization: Layouts automatically adjust view frames for right-to-left languages.
- Swift: LayoutKit can be used in Swift applications and playgrounds.
- Tested and production ready: LayoutKit currently has over 90 percent unit test coverage and is being used inside of recent versions of the LinkedIn and LinkedIn Job Search iOS apps.
LayoutKit provides a basic set of layouts that can be composed to create common interfaces. It is also possible to implement your own custom layouts.
This is what it looks like to declare a simple layout using LayoutKit:
Here is the view hierarchy that LayoutKit produces (with gray borders around the view frames for reference):
The LinkedIn and LinkedIn Job Search iOS apps saw immediate performance gains after converting interfaces from Auto Layout to LayoutKit. Views that were once slow to layout or scroll now layout instantly and scroll smoothly.
LayoutKit is eight times faster than Auto Layout and has performance that is comparable to writing manual layout code when benchmarked on an iPhone 6 running iOS 9.3.2 with a 20 cell UICollectionView using UICollectionViewFlowLayout.
LayoutKit is fast because of its specialized layout algorithms and because it does not create UIViews for layouts that do not require them. This means that developers are free to compose layouts without hurting performance.