Compose 에서 성능을 끌어올리기 위해서는 Stable 처리를 통해 리컴포지션을 최적화해야한다.
이러한 이유로 나는 Primitive Type, ImmutableList, val, Stable Marker 등 여러 선언 방식을 통해 해당 객체의 안정성을 Compose Compiler 에게 전달해왔다.
이를 통해 리컴포지션을 최적화했고, 이에 대해서는 이게 끝일 것이라 생각했는데 오늘 한 가지 알게 된 사실이 있어서 이를 공유해보고자 한다.
data class A(
val name: String,
val age: Int
)
위와 같은 data class 가 존재할 때, 이것의 프로퍼티는 모두 Primitive Type 이기 때문에 Compose Compiler 는 이를 안정적이라고 보고 Stable 하다고 본다.
나의 경우에도 기존 compose compiler 를 사용할 때, report 에서 stable 이라고 나왔기도 했고 그렇게 배웠기에 당연히 언제나 그럴 것이라고 생각했다.
그런데 이번 프로젝트를 진행하며 A 모듈에서 B 모듈의 인스턴스를 생성하여 Composable Parameter 로 넘겨주는데 Compose Stability Analyzer Plugin 에서 Unstable 하다고 나오는 것이다 !



하지만 아무리봐도 Unstable 로 추측될 이유가 없어서 이것저것 테스트해보던 와중, MoripCircleProgressSegment 가 다른 모듈에 존재한다는 것을 깨닫고 혹시나 싶어 Composable 과 같은 모듈에 클래스를 만들어보니, 이것은 또 정상적으로 Stable 처리가 되었다.

결론부터 말하자면 내 발생 원인은 이에 해당하지 않았다.
처음에는 이게 Plugin 문제인줄 알고, 이슈를 올릴까 하다가 안드로이드 문서가 있지 않을까 싶어 찾아봤는데 다음과 같은 내용이 있었다.

하지만 나의 경우 비원시 유형 [Color] 가 안정적으로 표시되어있고, 두 모듈 모두 Compose Compiler 설정이 되어 있었다.
혹시 Report 에서는 뭔가 다르지 않을까 싶어 뽑아보았지만, 결과는 다음처럼 Compile 과정에서 추론하는게 아닌 런타임 추론이 이뤄지고 있었다.

AI 의 답변을 빌린 것이므로 정확한 답변은 아니니, 주의 !
최종 확인한 결과 AI 가 답변한 게 맞았다 ! 이 정보에 대해서는 신뢰해도 될 듯 하다.
도무지 답을 알 수 없어 우선 Gemini 의 도움을 받았다.

내용은 위와 같다.
컴파일 과정에서 다른 모듈의 코드가 바이너리로 제공되는데, 이를 Stable Marker 나 compose_compiler_config.conf 를 통해 명시적으로 계약을 제공하지 않으면 이를 Runtime 에서 판정한다는 것이다.
https://github.com/skydoves/compose-stability-inference#61-stability-annotations 를 보면 3.3 / 5.4 / 6.2 / 6.4 에 관련 내용이 존재한다.
이유는 제미나이가 말해줬듯, Compose Compiler는 현재 컴파일 중인 모듈 안의 클래스는 필드까지 분석할 수 있지만, 다른 모듈/외부 라이브러리 타입은 내부 구조를 안전하게 다시 분석할 수 없기 때문 이라고 한다.
다른 모듈의 객체를 사용해야하는 경우, 명시적인 선언을 진행하지 않으면 Runtime 판정이 이뤄져 Compose Compiler 가 Stable 로 처리하는 것보다 성능이 뒤떨어질테니 Stable Marker 를 설정해주거나 compose_compiler_config.conf 를 등록해줘야할 것 같다 !