Compose 성능 최적화 하기 기본 지식
padding 8을 x로 변경해주면 어떻게 될까
값이 변경 될때 마다 리컴포지션이 일어 날 것 이다.
여기서 x가 아닌 람다를 통해 참조 하는 형식으로 한다면 Composition 단계를 생략이 가능하다.
Title(scroll.value)
...
fun Title(scroll:Int) {
val maxOffset = with(LocalDensity.current) { MaxTitleOffset.toPx() }
val minOffset = with(LocalDensity.current) { MinTitleOffset.toPx() }
Column(
modifier = Modifier
.heightIn(min = MaxTitleOffset)
.offset {
val offset = (maxOffset - scroll).coerceAtLeast(minOffset)
IntOffset(x= 0, y= offset.toInt())
}
.fillMaxWidth()
.background(Color.White)
){
사용자의 스크롤로 offset을 계산하는데, 이렇게 구성하면 사용자가 스크롤 할때마다 리컴포지션이 발생한다.
이를 람다로 표현하면
Title{ scroll.value }
...
fun Title(scrollProvider: () -> Int) {
val maxOffset = with(LocalDensity.current) { MaxTitleOffset.toPx() }
val minOffset = with(LocalDensity.current) { MinTitleOffset.toPx() }
Column(
modifier = Modifier
.heightIn(min = MaxTitleOffset)
.offset {
val offset = (maxOffset - scrollProvider()).coerceAtLeast(minOffset)
IntOffset(x= 0, y= offset.toInt())
}
.fillMaxWidth()
.background(Color.White)
){
람다로 값을 받기 때문에 스크롤을 내려도 리컴포지션이 일어나지 않는다.
Column {
for (item in items) {
key(item.id) {
Card(
...
키값을 지정해줘 반복문의 리컴포지션을 막아준다.
리스트 정렬 할때
fun Ex(
dataList: List<Data>
comparator: Comparator<Data>
)
LazyColumn {
items(dataList.sortedWith(comparator)) {
...
comparator는 정렬해주는 알고리즘
items안에서 정렬을 하면 모든시점에 변화가 있지 않아도 보여줄때마다 정렬을 함 -> 리소스 낭비
val sortedContacts = remember (dataList, sortComparator) {
dataList.sortedWith(sortComparator)
}
LazyColumn {
items(sortedContacts) {
...
remember를 사용해 정렬된 값을 저장하고 보여주면 필요할 때만 정렬을 함
계산 최소화 -> 계산의 위치를 안쪽에서 밖으로 빼주자.
var count by remember { mutableStateOf(0) }
...
Button(
onClick = count++
...
){
Text( "ADD $count")
count++
}
Text가 완성된뒤에 Text아래에 count++ 있기 때문에 실행되지 않음, 리컴포지션 안되서
이상태에서 버튼을 누를시 count가 바뀜
count를 사용하는 것은 리컴포지션이 됨
이때 리컴포지션이 되는 스코프 안에 Text안의 count++가 있기 때문에 작동함
이렇게되면 버튼을 누를시 무한 루프가 발생함
스코프안에서 값을 변하는 로직을 직접 쓰면 안됨
역방향쓰기는 이런 읽힌 이후에 쓰이는 코드를 말함