티스토리 뷰

300x250
300x250



지금까지 RecyclerView 에 대해 여러 주제로 기본 기능을 알아보았다.

이번 포스팅에서는 성능 개선에 대해 알아보려 한다.

 

참고로, 지난 포스팅 내용은 하단과 같다.

◼ ItemDecoration, clipToPadding, ItemAnimator

[Android/UI] - RecyclerView (10) - RecyclerView ItemAnimator

[Android/UI] - RecyclerView (9) - RecyclerView clipToPadding

[Android/UI] - RecyclerView (8) - RecyclerView 에 ItemDecoration 으로 구분선 및 여백 설정

 

◼ image + text 출력, click 처리, menu 출력, Item 삽입, 수정, 삭제, header, footer 달기

[Android/UI] - RecyclerView (7) - RecyclerView 에 header, footer 달기

[Android/UI] - RecyclerView (6) - RecyclerView item 추가, 수정, 삭제

[Android/UI] - RecyclerView (5) - RecyclerView item long click 시 popup menu 출력하기

[Android/UI] - RecyclerView (4) - RecyclerView item click 시 context menu 출력하기

[Android/UI] - RecyclerView (3) - RecyclerView item 의 click 처리하기

[Android/UI] - RecyclerView (2) - RecyclerView 에 image + text 출력하기



notifyDataSetChanged 와 notifyItemChanged 를 구분하여 사용하기

Adapter.notifyDataSetChanged() 를 호출하면 전체 아이템을 갱신하여 불필요한 갱신이 일어난다.

하단과 같이 변경된 아이템만 갱신하여 불필요한 갱신을 줄이자.

 

- notifyItemChanged : 특정 position 이 바뀌었을 경우

- notifyItemRangeChanged : 특정 영역이 바뀌었을 경우

- notifyItemInserted : 특정 position 에 데이터 하나를 추가할 경우

- notifyItemRemoved : 특정 position 에 데이터 하나를 제거할 경우

- notifyItemRangeRemoved : 특정 영역의 데이터를 제거할 경우

- notifyItemMoved : 특정 위치를 교환할 경우



ViewHolder 에서 Animation 사용 안 하기

ViewHolder 에서 itemView.animate() 를 호출하는 것 처럼 View 애니메이션을 사용하지 말자.

ListView 에서는 itemView 애니메이션을 처리하기 위해 getView() 에서 작업을 했다.

(View 재사용 관점에서 좋지 않다.)

 

RecyclerView 는 ItemAnimator 를 제공하고 있으니 이를 사용하면 된다.

[Android/UI] - RecyclerView (10) - RecyclerView ItemAnimator



ViewHolder 에서 ClickListener 처리하기

RecyclerView 에 ClickListener 는 ViewHolder 에서 처리하자.

Position 문제로 ClickListener 를 onBindViewHolder 에서 설정하는 사람이 많다.

하지만, onBindViewHolder는 계속 호출 되기 때문에 불필요한 리스너 설정이 계속 이뤄지게 된다.

onBindViewHolder 는 데이터를 View 에 바인딩하기 위해서만 사용하자

 

ViewHolder 에서는 position 을 getAdapterPosition 으로 확인할 수 잇다.

[Android/UI] - RecyclerView (3) - RecyclerView item 의 click 처리하기



setHasFixedSize(true)

RecyclerView 의 전체 크기가 고정되어 있다면 RecyclerView 가 갱신될 때 크기가 변경되어야하는지 확인하는 작업을 건너뛸 수 있다.

 

setHasFixedSize 를 true 로 설정하여 adapter 의 내용이 변경되어도 크기 변경에 따른 작업을 생략하자.



setItemViewCacheSize(size)

아이템 뷰가 화면 밖으로 나갔다가 다시 나타날 때 onBindViewHolder 함수의 호출을 줄여 성능을 향상할 수 있다.

RecyclerView 는 ViewHolder 를 강제하여 findViewById() 함수 호출을 줄였지만 뷰 객체만 재사용하여 onBindViewHolder를 통해 다시 그려줘야 한다.

 

setItemViewCacheSize 는 스크롤 되어 화면에 사라지는 뷰에 대해서 재사용되는 recycled view pool 에 들어가지 않고,

Cache 에 저장되어 다시 화면에 나왔을 때 onBindViewHolder 호출 없이 그대로 보여진다.



setHasStableIds(true)

아이템에 고유한 ID 를 부여하여 이미 바인딩 된 적이 있는 아이템에 대해서는 onBindViewHolder 호출을 줄여 성능을 향상할 수 잇다.

setHasStableIds 를 사용하면 getItemId를 구현해야한다. 또한 getItemId 는 고유한 ID 를 리턴 해야하며 중복된 ID 가 있을경우 Exception 을 발생시킨다.

 

5 개의 아이템이 있고 0 번째 아이템과 5 번째 아이템이 getItemId() 메서드로 리턴하는 ID 가 같다면 5 번째 포지션에서는 onBindViewHolder() 가 호출되지 않는다



RecyclerView - 중첩일 때 pool 공유

RecyclerView 가 중첩되어 있는 경우 RecyclerView 간의 ViewPool 을 공유하여 성능을 향상할 수 있다.

하단과 같이 가로, 세로 스크롤이 가능한 중첩된 RecyclerView 의 경우 scroll 시 심각한 성능 저하가 발생하게 된다.

 

 

RecyclerView 간의 ViewPool 을 설정하여 동일한 ViewPool 을 공유하게 하면 뷰 생성을 줄일 수 있다.



728x90
댓글