[Jetpack Compose] Strong Skipping Mode 에 대해 알아보자

오규성·2025년 11월 16일

Jetpack Compose 기초

목록 보기
13/13

현재 안드로이드 스튜디오 최신 버전에서는 Strong Skipping Mode 가 기본적으로 활성화 되어 있으나, 기존에는 이러한 기능이 없었다.

또한 Strong Skipping Mode 가 기본적으로 활성화 되어 있다고 하더라도 이 기능이 정확히 어떤 것인지 알 수 있도록 공유하는 것이 좋을 것이라 생각되어 글을 쓰게 되었다.


# Strong Skipping Mode 란?

restartable 인 경우 Unstable 한 객체임에도 Compose Compiler 가 해당 객체를 Skippable 로 간주, Compose Runtime 은 이를 우선 동일성 체크 후 동등성 체크를 거치게 된다.

이 Strong Skipping Mode 를 사용하기에 앞서 StableUnstable 에 간단하게 알아야한다.

Stable 의 경우 Compose 가 안정적인 객체로 판단하여 Skippable 하게 설정하는데, 리컴포지션 과정에서 equals 체크를 진행하며 이전과 같다고 판단되면 Skip 할 수 있게 된다.
Unstable 의 경우 Compose 가 안정적이지 못한 객체로 판단하여 값이 변하지 않더라도 Instance 가 다르다면, Skipping 을 하지 못하여 Recomposition 이 발생한다.

Stable 의 경우 Primitive Type 이거나, @Stable Marker 를 사용하여 만들어졌거나, class 내부의 프로퍼티가 모두 Stable 이어야 한다.

List 와 같은 interface 는 구현에 의해 내부가 변할 수 있으므로 Unstable 이다.

Lambda 의 경우 값을 캡처하지 않거나 안정적인 객체를 캡처하면 Stable 이지만, Unstable 객체를 캡처하는 경우 불안정하게 작동된다.

# 사용 예시 코드 작성 (일반 객체)

class MainActivity() : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        enableEdgeToEdge()
        setContent {
            Scaffold {
                Column(Modifier
                    .fillMaxSize()
                    .padding(it)
                ) {
                    Parent()
                }
            }
        }
    }
}

@Composable
fun Parent(){
    var count by remember { mutableStateOf(1) }
    val list = remember { listOf(1, 2, 3) }

    Child(list)
    Child2(count)
    Button({ count++ }) { }
}

@Composable
fun Child(list: List<Int>){
    Text(text = list.toString())
}

@Composable
fun Child2(count: Int){
    Text(text = count.toString())
}

위 코드에서 Child 의 경우 Unstable 인 List<Int> 를 파라미터로 받고 있다. 이러한 이유로 Button 을 클릭하여 Parent 를 리컴포지션 시키면 Strong Skipping Mode 에 따라 Recomposition 에 차이가 발생한다.

1. Strong Skipping Mode 비활성화

Strong Skipping Mode 가 꺼져있을 때를 확인해보자.

앱을 실행하여 버튼을 3번 누르게 되는 경우, List 가 바뀌지 않았음에도 Unstable 하여 Child 에 리컴포지션이 발생하게 된다.

2. Strong Skipping Mode 활성화

List 는 Unstable 하지만 Strong Skipping Mode 에 의해 Skippable 하게 되었고, 동등성 비교에서 true 되어 Skip 되었다.

Child.Text 의 경우 Child 가 Recomposition 되지 않았으니 아무런 동작하지 않는다.


# 사용 예시 코드 작성 (Lambda 객체)

@Composable
fun Parent(){
    val list = remember { mutableListOf(1, 2, 3) }
    var count by remember { mutableStateOf(0) }

    Child { Timber.d(list.toString()) }

    Button({ count++ }) { Text(text = "카운트 증가") }
    Text(text = count.toString())
}

@Composable
fun Child(lambda: () -> Unit){
    Button(lambda) { Text(text = "람다") }
}

1. Strong Skipping Mode 비활성화

2. Strong Skipping Mode 활성화

Lambda 내부에서 unstable 객체를 캡처하였지만, Strong Skipping Mode 에 의해 Skippable 하게 되었고 $composer.changedInstance(list) 가 true 이기에 스킵 되었다.

profile
안드로이드 개발자 Gyu 의 개발 블로그 !

0개의 댓글