[Compose] 성능 최적화

KSang·2024년 4월 30일
1

TIL

목록 보기
93/101

Compose 성능 최적화 하기 기본 지식

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)
	){

람다로 값을 받기 때문에 스크롤을 내려도 리컴포지션이 일어나지 않는다.

key 사용

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++가 있기 때문에 작동함
이렇게되면 버튼을 누를시 무한 루프가 발생함

스코프안에서 값을 변하는 로직을 직접 쓰면 안됨

역방향쓰기는 이런 읽힌 이후에 쓰이는 코드를 말함

0개의 댓글