Mastering Swift's Development Blog

Follow Us On Twitter
  • Jon Hoffman

LazyHStack and LazyVStack

Updated: Jul 21

Using stacks in SwiftUI enables us to very easily build complex user interfaces with ease. Anyone that has built an app, and has used stacks with SwiftUI, can attest to this. In this post I would like to demonstrate when we should consider using the LazyHStack and LazyVStack instead of the HStack and VStack and why it could greatly improve your app's performance.

The VStack and HStack attempts to load all their content up front, when the whole view loads. While this works well, with acceptable performance, for a small number of elements, when we are attempting to load in a large number of items this can be detrimental to the performance of our app. This is where the LazyVStack and LazyHStack come in.

When using the LazyVStack and LazyHStack with a scroll view, the elements will only load when they come into view. For example, in the Mastering Swift Cocktail app, we use two LazyHStacks in the ContentView for the list of popular drinks and the list of ingredients in the user’s bar. This prevents the applications from trying to go out and load all the images at once and only loads them when/if an they becomes visible. If you are not familiar with our open-source cocktails app you can read about it, with links to the source code, here.

For the Mastering Swift Cocktail App, I mainly used the LazyHStack to prevent images, that may not be seen, from loading until they are needed. This did increase performance of the app, however I did this mainly to prevent images from loading if it was not necessary. For other apps, that do have large data sets, this could greatly increase performance. Let’s take a look at this and see for ourselves.

Create two iOS apps that use SwiftUI, one titled HStack_Test and the other LazyHStack_Test. In the ContentView of the LazyHStack_Test put the following code:

struct ContentView: View {
    var body: some View {
        ScrollView(.horizontal) {
            LazyHStack {
                ForEach(0..<10000) { item in
                    VStack {
                        Text("Number \(item)")
                        RoundedRectangle(cornerRadius: 10)
                            .frame(height: 35)
            .frame(height: 200)

In the ContentView of the HStack_Test app put the same code except change the “LazyHStack” to “HStack”. If we install both apps on either a simulator or an iOS device and run them, you will notice that LazyHStack_Test app starts up significantly faster as compared to the HStack_Test app. It is so much faster you can see the difference with your eyes.

The reason the LazyHStack_Test app loads so much faster is it doesn’t attempt to load all 10000 elements when the view loads. Instead, it loads the elements as they become visible. I would recommend, as a good rule of thumb, that whenever you combine a VStack or HStack with a scroll view that you consider using the LazyVStack or LazyHStack version instead.


Mastering Swift 5.3

The sixth edition of this bestselling book, updated to cover through version 5.3 of the Swift programming language




Protocol Oriented Programming

Embrace the Protocol-Oriented design paradigm, for better code maintainability and increased performance, with Swift.