title: Jetpack Compose Smart Recomposition
body: <p>I'm doing experiments to comprehend recomposition and smart recomposition and made a sample</p>
  <p><a href="https://i.stack.imgur.com/JFOs3.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/JFOs3.gif" alt="enter image description here" /></a></p>
  <p>Sorry for the colors, they are generated with Random.nextIn() to observe recomposition visually, setting colors has no effect on recomposition, tried without changing colors either.</p>
  <p>What's in gif is composed of three parts</p>
  <p><strong>Sample1</strong></p>
  <pre><code>@Composable
  private fun Sample1() {
  
      Column(
          modifier = Modifier
              .background(getRandomColor())
              .fillMaxWidth()
              .padding(4.dp)
      ) {
          var counter by remember { mutableStateOf(0) }
  
  
          Text(&quot;Sample1&quot;, color = getRandomColor())
  
          Button(
              modifier = Modifier
                  .fillMaxWidth()
                  .padding(vertical = 4.dp),
              colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
              onClick = {
                  counter++
              }) {
              Text(&quot;Counter: $counter&quot;, color = getRandomColor())
          }
      }
  }
  </code></pre>
  <p>I have no questions here since smart composition works as expected, <code>Text</code> on top is not reading changes in <code>counter</code> so recomposition only occurs for <code>Text</code> inside <code>Button</code>.</p>
  <p><strong>Sample2</strong></p>
  <pre><code>@Composable
  private fun Sample2() {
      Column(
          modifier = Modifier.background(getRandomColor())
      ) {
  
          var update1 by remember { mutableStateOf(0) }
          var update2 by remember { mutableStateOf(0) }
  
          println(&quot;ROOT&quot;)
          Text(&quot;Sample2&quot;, color = getRandomColor())
  
          Button(
              modifier = Modifier
                  .padding(start = 8.dp, end = 8.dp, top = 4.dp)
                  .fillMaxWidth(),
              colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
              onClick = {
                  update1++
              },
              shape = RoundedCornerShape(5.dp)
          ) {
  
              println(&quot; Button1️&quot;)
  
              Text(
                  text = &quot;Update1: $update1&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
  
          }
  
          Button(
              modifier = Modifier
                  .padding(start = 8.dp, end = 8.dp, top = 2.dp)
                  .fillMaxWidth(),
              colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
              onClick = { update2++ },
              shape = RoundedCornerShape(5.dp)
          ) {
              println(&quot; Button 2️&quot;)
  
              Text(
                  text = &quot;Update2: $update2&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
          }
  
          Column(
              modifier = Modifier.background(getRandomColor())
          ) {
  
              println(&quot; Inner Column&quot;)
              var update3 by remember { mutableStateOf(0) }
  
              Button(
                  modifier = Modifier
                      .padding(start = 8.dp, end = 8.dp, top = 2.dp)
                      .fillMaxWidth(),
                  colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
                  onClick = { update3++ },
                  shape = RoundedCornerShape(5.dp)
              ) {
  
                  println(&quot;✅ Button 3️&quot;)
                  Text(
                      text = &quot;Update2: $update2, Update3: $update3&quot;,
                      textAlign = TextAlign.Center,
                      color = getRandomColor()
                  )
  
              }
          }
  
          Column() {
              println(&quot;☕️ Bottom Column&quot;)
              Text(
                  text = &quot;Sample2&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
          }
  
      }
  }
  </code></pre>
  <p>It also works as expected each mutableState is updating only the scope they have been observed in. Only <code>Text</code> that observes <code>update2</code> and <code>update3</code> is changed when either of these mutableStates are updated.</p>
  <p><strong>Sample3</strong></p>
  <pre><code>@Composable
  private fun Sample3() {
      Column(
          modifier = Modifier.background(getRandomColor())
      ) {
  
  
          var update1 by remember { mutableStateOf(0) }
          var update2 by remember { mutableStateOf(0) }
  
  
          println(&quot;ROOT&quot;)
          Text(&quot;Sample3&quot;, color = getRandomColor())
  
          Button(
              modifier = Modifier
                  .padding(start = 8.dp, end = 8.dp, top = 4.dp)
                  .fillMaxWidth(),
              colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
              onClick = {
                  update1++
              },
              shape = RoundedCornerShape(5.dp)
          ) {
  
              println(&quot; Button1️&quot;)
  
              Text(
                  text = &quot;Update1: $update1&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
  
          }
  
          Button(
              modifier = Modifier
                  .padding(start = 8.dp, end = 8.dp, top = 2.dp)
                  .fillMaxWidth(),
              colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
              onClick = { update2++ },
              shape = RoundedCornerShape(5.dp)
          ) {
              println(&quot; Button 2️&quot;)
  
              Text(
                  text = &quot;Update2: $update2&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
          }
  
          Column {
  
              println(&quot; Inner Column&quot;)
              var update3 by remember { mutableStateOf(0) }
  
              Button(
                  modifier = Modifier
                      .padding(start = 8.dp, end = 8.dp, top = 2.dp)
                      .fillMaxWidth(),
                  colors = ButtonDefaults.buttonColors(backgroundColor = getRandomColor()),
                  onClick = { update3++ },
                  shape = RoundedCornerShape(5.dp)
              ) {
  
                  println(&quot;✅ Button 3️&quot;)
                  Text(
                      text = &quot;Update2: $update2, Update3: $update3&quot;,
                      textAlign = TextAlign.Center,
                      color = getRandomColor()
                  )
  
              }
          }
         //  Reading update1 causes entire composable to recompose
          Column(
              modifier = Modifier.background(getRandomColor())
          ) {
              println(&quot;☕️ Bottom Column&quot;)
              Text(
                  text = &quot;Update1: $update1&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
          }
      }
  }
  </code></pre>
  <p>Only difference between <strong>Sample2</strong> and <strong>Sample3</strong> is <code>Text</code> at the bottom is reading update1 mutableState which causing entire composable to be recomposed. As you can see in gif changing <code>update1</code> recomposes or changes entire color schema for Sample3.</p>
  <p>What's the reason for recomposing entire composable?</p>
  <pre><code>        Column(
              modifier = Modifier.background(getRandomColor())
          ) {
              println(&quot;☕️ Bottom Column&quot;)
              Text(
                  text = &quot;Update1: $update1&quot;,
                  textAlign = TextAlign.Center,
                  color = getRandomColor()
              )
          }
      }
  </code></pre>