# LazyStack

레이지스택은 on-demand 방식으로 동작하는 스택뷰이다. 스크롤시 일반 스택뷰를 임베딩하면 모든 뷰가 스크롤뷰 생성과 동시에 초기화되어 메모리상에 살아있게 되지만, 레이지 스택은 뷰에 onAppear되는 뷰에 따라 동적으로 그려지는 방식이다.

간단한 예시에서는 레이지스택과 일반 스택의 차이가 보이지 않지만 공식문서에서는 일반 스택을 기반으로 먼저 구현을 시도해보고 성능 이슈가 발생했을때 레이지 스택 사용을 권장한다.

When choosing the type of stack view to use, always start with a standard stack view and only switch to a lazy stack if profiling your code shows a worthwhile performance improvement.

일반 스택의 장점은 자식 뷰의 로드가 한번에 이루어지므로 레이아웃 생성과 계산이 빠르고 신뢰성이 보장된다. 레이지 스택은 성능을 위해 레이아웃 계산 정확도를 트레이드 오프 하는 것이다.

# 성능이슈 체크

성능이슈 비교를 위해서는 intruments tool을 통해 스탠다드 스택과 레이지 스택에 대한 비교를 진행한다. 레이지 스택을 사용하기 위한 임계 수치가 공식 문서에서 제공되고 있지는 않지만, 두 스택 생성에 대한 성능 비교 그래프를 확인해보고 주관적으로 판단하면 될 것이다.

주의할 점은 성능 체크는 시뮬레이터가 아닌 실 기기로 진행해야 한다는 것이다.

Never profile your code using the iOS simulator. Always use real devices for performance testing.

# 기타 내용

# 1. 어차피 모든 뷰를 그려줘야 한다면

Lazy stacks incur a small amount of extra overhead, both in time and memory, to handle the bookkeeping for what views have and have not been instantiated. In cases where all the views have to be instantiated anyway, that overhead is pure cost with no benefit.

앱 사용자에 의해 모든 뷰를 결국 그려야 한다면 레이지 스택에서 추가되는 비용은 불필요하다. 레이지 스택에 추가되는 비용은 어떤 뷰가 로드되기 위해 메모리 내에 예약되어야 하는지, 어떤 뷰가 초기화되면 안되는 지에 대한 내부적 계산이 이루어지는 부분으로 존재한다.

어차피 모든 뷰를 스크롤하여 그리게 될거라면 애초부터 스탠다드 스택으로 스크롤을 구성하는 것이 추가 비용을 지불하지 않게되는 것이다.

# 2. 동적 레이아웃 수치 계산으로 인한 문제

But now suppose that LazyVStack includes horizontally scrolling ScrollViews within it—think rows with photo thumbnails. In the general case, all the views in the horizontally scrolling ScrollView have to be instantiated eagerly so that SwiftUI can determine the height of the row.

LazyVStack각 요소가 다시 한번 HStack을 포함하는 형태라면 레이아웃 수치가 동적으로 이 루어지는 과정에서 의도한 대로 UI 구성이 이루어지지 않을 수 있다.

레이지 스택이 아닌 스탠다드 스택으로 구성하는 경우 모든 인스턴스가 생성되어 있기 때문에 레이아웃도 정확하게 계산된 상태이다. 따라서 의도한 대로 UI가 구성될 수 밖에 없다.

# Reference

  1. Apple document - Creating performant scrollable stacks (opens new window)
  2. Apple developer forums - What are the downsides to using lazy stacks? (opens new window)