-
ScrollablePositionedList.builder를 사용할 때 성능을 최적화하려면카테고리 없음 2024. 11. 28. 23:04
ScrollablePositionedList.builder를 사용할 때 성능을 최적화하려면 다음과 같은 방안을 고려할 수 있습니다. 이 위젯은 특히 긴 리스트를 처리할 때 최적화를 통해 렌더링 비용과 메모리 사용량을 줄이는 것이 중요합니다.
1. itemCount와 데이터 제공
itemCount를 명시하여 불필요한 데이터 계산을 피하세요.
ScrollablePositionedList.builder( itemCount: messages.length, // 전체 메시지 개수 제공 itemBuilder: (context, index) { final message = messages[index]; return MessageWidget(message: message); }, reverse: true, // 가장 최근 메시지가 위로 오도록 initialScrollIndex: 0, // 기본 위치를 마지막 메시지로 );
- 효과: itemCount가 지정되면 Flutter는 빌드할 범위를 더 정확히 예측하고 최적화된 렌더링을 수행합니다.
2. addAutomaticKeepAlives, addRepaintBoundaries 설정
리스트 빌딩 옵션으로 성능 튜닝을 진행할 수 있습니다.
ScrollablePositionedList.builder( itemCount: messages.length, itemBuilder: (context, index) { return MessageWidget(message: messages[index]); }, reverse: true, addAutomaticKeepAlives: false, // 불필요한 상태 유지 비활성화 addRepaintBoundaries: false, // Repaint 영역 최소화 );
- addAutomaticKeepAlives: 상태 유지가 불필요한 경우 false로 설정.
- addRepaintBoundaries: Repaint 범위를 최소화해 성능 개선.
3. reverse 최적화
reverse: true는 새로 추가된 메시지가 리스트 상단에 배치되도록 합니다. 그러나 성능에 문제가 발생하면 데이터 리스트를 직접 뒤집고 reverse: false를 사용해보세요.
ScrollablePositionedList.builder( itemCount: messages.length, itemBuilder: (context, index) { final message = messages[messages.length - 1 - index]; // 리스트를 역순으로 매핑 return MessageWidget(message: message); }, reverse: false, // 데이터 리스트를 직접 뒤집었으므로 reverse 비활성화 );
- 효과: reverse가 내부적으로 처리하는 연산을 줄이고 더 나은 성능을 얻을 수 있습니다.
4. Lazy Loading 구현
ScrollablePositionedList를 사용할 때 무한 스크롤을 구현하면 초기에 로드되는 데이터 양을 줄일 수 있습니다.
final int initialLoadCount = 50; // 초기 로드 메시지 수 List<ChatMessage> displayedMessages = messages.take(initialLoadCount).toList(); // 더 가져오기 메서드 void loadMoreMessages() { setState(() { final additionalCount = 50; // 한 번에 추가 로드할 메시지 수 displayedMessages = messages.take(displayedMessages.length + additionalCount).toList(); }); } // 스크롤 끝 감지 ScrollablePositionedList.builder( itemCount: displayedMessages.length, itemBuilder: (context, index) { if (index == displayedMessages.length - 1 && displayedMessages.length < messages.length) { loadMoreMessages(); // 스크롤 끝에서 추가 로드 } return MessageWidget(message: displayedMessages[index]); }, reverse: true, );
- 효과: 초기 로딩 데이터를 제한하고, 스크롤 이벤트에 따라 데이터를 점진적으로 로드.
5. Indexed Cache 사용
ScrollablePositionedList는 자동으로 IndexedScrollController를 활용하지만, 추가로 캐싱하여 성능을 향상할 수 있습니다.
final ItemScrollController itemScrollController = ItemScrollController(); ScrollablePositionedList.builder( itemCount: messages.length, itemBuilder: (context, index) { return CachedWidget(index: index, child: MessageWidget(message: messages[index])); }, itemScrollController: itemScrollController, reverse: true, );
CachedWidget처럼 특정 아이템을 캐싱하는 위젯을 사용해 이전에 빌드된 위젯을 재활용하면 성능을 높일 수 있습니다.
6. Flutter DevTools로 성능 분석
Flutter DevTools에서 ScrollablePositionedList의 렌더링 성능을 분석하세요.
- Jank 탐지: 프레임 드롭 여부 확인.
- Rebuild Count: 불필요한 빌드가 발생하는 경우 최적화.
요약
- itemCount와 데이터 리스트 최적화.
- addAutomaticKeepAlives와 addRepaintBoundaries 설정.
- 데이터 리스트를 뒤집어 reverse 로직 간소화.
- Lazy Loading 구현으로 초기 데이터 로드 제한.
- Indexed Cache를 활용한 위젯 재사용.
- DevTools로 성능 병목 식별.
위의 방법을 조합하여 성능을 최적화하면 원활한 스크롤 경험을 제공할 수 있습니다! 🚀