One challenge in Android development is achieving smooth UI performance. Developers can spend a lot of time optimizing, squeezing out every bit of speed from their UI code, and yet still experience lag and dropped frames in complex scenarios.
At Facebook, this problem is relevant to us because more than 1 billion people use our app on Android every month. The devices they use range from typical, low-power phones to the latest high-end models. We want to support best-in-class performance regardless of how people are accessing our products on Android.
Last year, we shared that we were working on a new framework for creating efficient UIs on Android. Building on the success we've seen with React, we wanted to deliver a simple API for defining user interfaces from declarative components, with performance as the primary goal. We designed the framework to be fast, even for our complex products such as News Feed.
We've started using this framework across many surfaces in our Android apps, including Facebook, Messenger, Facebook Lite, and Workplace, and have seen an improvement in scroll performance of up to 35 percent. Today, we're excited to open-source it as Litho, and we hope to enable Android developers everywhere to develop more efficient UIs while writing simpler code.
Device screens refresh at a rate of 60 frames per second. Providing smooth performance means we need to be able to render changes to our UI continuously every 16 ms. If we don’t, it can lead to dropped frames and a poor experience.
As UIs become increasingly sophisticated, it gets harder to complete all the rendering work that needs to get done in this time frame. This proves to be especially challenging with dynamic scrolling surfaces, as new pieces of UI are constantly being introduced onscreen.
Android addresses this with RecyclerView, a dynamic UI container that is able to display elements from large data sets by creating only enough views to fill the screen and then recycling and reusing them as the UI scrolls. Whenever a new item is about to become visible, RecyclerView will recycle or create the appropriate view, bind the view with the right data, and then finally measure, lay out, and draw it onscreen. Fitting all these operations within the 16 ms the main thread has to compute a new frame can be challenging.
RecyclerView also keeps views in different pools depending on their type. So for UIs with many different view types, the same view is less likely to be reused frequently. This means that more views are held in memory while new views are constantly being created, which affects both memory and performance.
Litho is designed to be faster and more efficient when working with scrolling surfaces. It aims to improve performance by moving the heavy work to a background thread and spreading the rendering work across multiple frames.
By using the React declarative model and the Yoga layout system, Litho is able to decouple the layout operations from Android views. This allows us to move the CPU-intensive measure and layout operations to the background thread, saving milliseconds.
Finally, Litho breaks down complex views into smaller pieces such as text, images, and videos, and renders them incrementally, spreading the work that needs to be done across multiple frames. It also recycles those smaller pieces and can recombine them in a virtually infinite number of ways, reducing the total number of views that need to be created and stored in memory.
Since being used across our apps, Litho has delivered great results, including an improvement in scroll performance of up to 35 percent, better memory behavior with complex lists, and easier-to-test UI code.
With its simple, declarative API, Litho frees developers from painstakingly hand-optimizing their UIs. Litho lays out components ahead of time in a background thread, and renders incrementally to deliver best-in-class performance for your users. We believe Litho solves challenges that are not unique to Facebook. This is why we're excited about what Litho can do for Android developers everywhere.