Increase Android Layout Rendering Performance by Lazy Loading During App’s Runtime
By: Wendy Yanto
Tags: Software Development, Android, Performance, Viewstub

Nowadays, modern Android UI is getting even more complex. Complex android layout affects your app performance in rendering layout. Thus optimising Android XML layouts is getting even more important than ever. Of course currently there’s a lot of ways provided by Android core team to help Android engineer to increase its UI complex layout performance. One of the ways is by implementing ViewStub .

A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime.

By using ViewStub , it allows us to speed up first time layout rendering by inflate complex UI component lazily during app is running. By using this approach, complex component in the layout rendering can be delayed in order to speed up app layout startup time to user. It works well on use cases such as delaying view that might show in the future based on user interactions. One particular usage that comes in mind when delaying view that might (or not) shown to user is when user scrolls through the UI. In Android, we use ScrollView to wrap long UI layout in the XML file.

By using ScrollView , our app will only show part of layout that fit to the screen to the user while other component will remain hidden on the top or under the visible UI layout until user scrolls into it. We can make use of this behaviour to defer complex layout rendering by making it a ViewStub with hidden complex layout at first place until user scrolls to the deferred layout component, our app will then render its complex component’s layout by invoking inflate of the ViewStub . To make this magic works, each ViewStub must aware of its current position in the layout and always observe on user’s scroll action until it is shown and inflated.

In order to encapsulate ViewStub logic to observe on user’s scroll action, we’re going to make a custom view that is reusable. By using custom view, it will be very easy to implement lazy load by importing it only in our XML of layout without any code in kotlin or java . First, we’re going to create a new class that will extend on simplest android view that is LinearLayout . By wrapping a ViewGroup on our ViewStub , it will help us to setup placeholder such as Loading... text or any image during lazy load process is running. During the initialisation of our custom view, we are going to add ViewStub programmatically into our custom view like the following code.

After that, let’s setup our custom view XML attribute. Our custom view XML attribute will have the layout reference of the complex layout we’re delaying that our ViewStub need. Because our component will be calculating its position in the parent layout, we will need the value of the actual height of its parent layout. Therefore, we also need to pass parent’s XML ID into our custom view XML attribute. By passing our parent’s layout resource ID to the custom view, we will be able to get its reference by using rootView.findViewById(parentResourceID) and retrieve its height by using measuredHeight . Following is the example of XML attribute of our lazy load component.

Here’s the code to retrieve the value in the custom view and set layout resource reference to our ViewStub to inflate it during runtime.

That’s the end of custom view initialisation logic. Let’s now get started with lazy load implementation in our ViewStub .

First thing first, our ViewStub component should know its current Y position in the parent layout upon it has been rendered to the UI. In order to achieve it, we will use getGlobalVisibleRect() to get its current X and Y of ViewStub’s global coordinate in the parent layout. This logic should be execute only if UI has been rendered completely. Thus we will be using onGlobalLayout callback from ViewTreeObserver to execute getGlobalVisibleRect() to ensure our component has the exact X and Y coordinates in the parent layout.

After that, we need to setup a callback logic when user attempts to scroll, our ViewStub should aware if it has already been shown to the user or not. To check if ViewStub already shown to user or not, we will need to check if bottom coordinates in the screen shown to user has intercepted ViewStub component or not. It can be done easily by verifying if bottom coordinates of the screen has higher or equal value than top Y coordinate of ViewStub .

In order to get the current bottom Y coordinate of the screen, we need to sum current scrolled top Y coordinate and our parent layout’s height. By using scrollY of ScrollView , we will be able to directly access the value of current scrolled top Y coordinate. Finally, we can execute our logic to check if the ViewStub is already shown or not by checking if by using the following code:

If it returns true then it means that ViewStub ’s coordinate has been intercepted and shown to the user therefore we can inflate our ViewStub immediately and update its flag to prevent multiple execution of ViewStub loading layout resource dynamically. In the end, don’t forget to remove our preset placeholder (if added in the first place) by removing it’s view right away once it’s loaded.

Here’s the demo of our lazy load component

Lazy Load Component Demo

In addition, I have provided several features in the library that might be useful for us such as placeholder of text or even image which I didn’t discuss in this Medium article. Those placeholders will be shown temporary to user until our ViewStub component replace it with the intended layout by removing the component completely from the view upon inflate() is called in the ViewStub .

That’s the end of this lazy load component in Android using ViewStub article. Hopefully it will be useful to improve our UI rendering performance. If you have any feedback about ViewStub , I’m open for discussing. Let’s learn together. Thank you !

Full Source code: https://github.com/WendyYanto/android-lazy-load-component

My Github : https://github.com/WendyYanto