DEV Community

Cover image for What the key parameter in LazyColumn is actually doing | A deep dive
Tristan Elliott
Tristan Elliott

Posted on

What the key parameter in LazyColumn is actually doing | A deep dive

Table of contents

  1. Introduction
  2. What should be recomposed?
  3. The solution to this is the key composable
  4. Resources

My app on the Google play store

Introduction

  • I originally posted this on stack overflow, HERE

  • This is a bit of a deep dive I did after reading the Lifecycle of composables documentation. I would highly recommend that you read that documentation as it will give you a deeper understanding on what the heck goes on in compose

  • This is an intermediate level post. However, if you are a beginner I still think you could benefit from reading this blog post

What should be recomposed?

  • When considering what composable should be recomposed, the compose compiler fist checks each distinct composable. We can use the documentation to define distinct as:

The instance of a composable in Composition is identified by its call site. The Compose compiler considers each call site as distinct. Calling composables from multiple call sites will create multiple instances of the composable in Composition.

call site : is the source code location in which a composable is called. This influences its place in Composition, and therefore, the UI tree

  • so basically a composable is distinct if it is called in different spots in your code, even if the composables are the same:
Column {  
    YourComposable()
    YourComposable() 
    }
Enter fullscreen mode Exit fullscreen mode
  • Both instance of YourComposable() are considered distinct by the compiler
  • So if a composable is distinct(called from different places in your code) the compose compiler will know to only recompose the composable that has a state change

  • However, what happens when you have a for loop like this:

@Composable
fun MoviesScreen(movies: List<Movie>) {
    Column {
        for (movie in movies) {
            // MovieOverview composables are placed in Composition given its
            // index position in the for loop
            MovieOverview(movie)
        }
    }
}

Enter fullscreen mode Exit fullscreen mode
  • MovieOverview is being called from the same call site(not distinct). To combat this scenario the compose compiler will use the execution order in addition to the call site to keep the instances distinct

  • This will work fine as long as values are only removed and added to the bottom of the list(index of length-1). But once the list changes by either adding to the top or the middle of the list. Or by removing or reordering items ,it'll cause a recomposition in all MovieOverview calls whose input parameter has changed position in the list

  • if you have a list of length 100 and you insert at item at index 50, then all the composables from index 99-50 will get recomposed even though they have not had their state changed

The solution to this is the key composable

  • the key composable allows the compose compiler to identify each composable as distinct and eliminate the wasteful recompositions
  • the key must be unique to the list and will crash if it is not
@Composable
fun MoviesScreenWithKey(movies: List<Movie>) {
    Column {
        for (movie in movies) {
            key(movie.id) { // Unique ID for this movie
                MovieOverview(movie)
            }
        }
    }
}

Enter fullscreen mode Exit fullscreen mode
  • The code block above can now have its items, rearranged, removed and added to at any index and no wasteful recompositions will occur.

What is the LazyColumn items key parameter purpose ?

  • It serves the exact same role. LazyColumn just has built-in support for the key composable
@Composable
fun MoviesScreenLazy(movies: List<Movie>) {
    LazyColumn {
        items(movies, key = { movie -> movie.id }) { movie ->
            MovieOverview(movie)
        }
    }
}

Enter fullscreen mode Exit fullscreen mode
  • If we did not provide the key and tried to remove, add or reorganize we would face the exact same wasteful recompositions mention earlier

Resources

Lifecycle of composables documentation

Conclusion

  • Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.

Top comments (0)