ShirinkWrap vs Slivers | Flutter 디코딩 하기

valas·2022년 1월 25일
1

플러터 디코딩

목록 보기
5/6

동영상

https://www.youtube.com/watch?v=LUqDNnv_dh0

요약

플러터를 개발하면서 처음 만들어보는 위젯 중 하나는 ListView 다. 왜나하면 스크롤 할 위젯이 필요할 때 만들기 쉬우니까.
한 번 익숙해지면 스크롤 할 때 매우 편리하다. Viewport(보이는 영역) 전체를 거치는 여러 위젯 중 하나가 ListView다.
ListView를 만들다 보면 Viewport가 깨지거나, 에러가 나오면서 안될 때가 있다.
이럴 때 해결법을 찾다 보면 ShrinkWrap을 참으로 해보라는 것을 많이 봤을 것이다. 이러면 에러가 없어지고 Scrolling Land엔 평화가 찾아온다.
문제는 여전히 에러가 다시 생길 가능성이 있다는 것이다.
ShrinkWrap은 비용이 많이 든다. 이유를 찾아보자.

당신은 크루즈 배의 덱의 구멍을 보고 있다.
갑자기 많은 물고기들이 지나간다. 당신은 가만이 있지만, 물고기 무리들은 전체의 일부 보일 것이다. 얼마나 많은 물고기가 지나가야 할지 모른다. 무한히 있을수도 있지만, 어쨋든 한 번에 몇마리만 볼 수 있다.
이것이 ListView의 동작 방식이다.
이 구멍은 ListView에서 보이는 부분이고, 물고기가 지나가는 것은 위젯들이다.

이런 Viewport를 다루는 방법은 Flutter를 다룰 때 매우 중요하다.
만약 2개의 보이는 구멍이 있다면?
이건 불가능하다.
리스트뷰의 전체크기를 알아내고, 사용자에게 보이는 영역에 보여주며 하나의 위젯으로 동작한다.
이것이 ShrinkWrap이 하는 일이다. 또 강제로 전체 위젯을 만든다.

왜 이것이 성능에 문제가 있을까?

내부 목록 중 어떤 것엔 여러 위젯이 포함된다. 특히 애니메이션이 Viewport에 보이려면 완전히 렌더링 되야한다. 이 때 프레임이 drop, jank, stutter 될 수 있다.
이 리스트가 길면 길어질 수록, 중요한 것이 있으니 다음을 보자

final outerListChildren = <ListView>]
	ListView(
    	shrinkWrap: true, 
        physics: const NeverScrollableScrollPhysics(), 
        children: <Widget>[]
        ),];
        
return ListView.builder(
	itemBuilder: (context, index){
    	return outerListChildren[index];
        }
    )

아이템이 리스트뷰인 리스트뷰가 있다. 아이템 리스트뷰의 shrinkWrap이 참이고, 스크롤되지 않게 설정 하자.
플러터는 UI를 렌더링 할 순 있다.
성능 문제가 있지만, 다행히 해결법은 쉽다.

  1. outerList를 감싸는 ListView를 CustomScrollView 로 바꾸자.
  2. outerListChildren를 SliverList 로 바꾸자.
  3. outerListChildren의 내부 아이템을 delgate가 필요한 SliverList로 바꾸자.

이 때 SliverChildBuilderDelegate를 사용하면 쉽게 할 수 있다.

final outerListchildren = <SliverList>[
	SliverList(
    	delegate: SliverChildBuilderDelegate(
        	(context, index) => _myWidget[index],
            childCount: _myWidgets.length,
        ),
	),
    ...
   ];
   return CustomScrollView(
	   children: outerListChildren,
       )

위와 같이 하면 효율적으로 리스트 내부에 리스트를 구현할 수 있다.
viewport에만 보이는 물고기만 렌더링하면 된다.

결론

ShrinkWrap: true가 있는지 확인해보고
있다면 Sliver를 사용하자.

Dartpad 연습

https://goo.gle/3oCRRTt

0개의 댓글