Lazy를 사용하면 화면에 표시될때만 렌더링 되고 이로 인해 메모리 사용량이 줄고 앱의 성능 저하를 막아준다고 알고 있었습니다. 그래서 스크롤 뷰를 사용할 때 뷰의 양이 많으므로 LazyVStack을 사용해서 구현을 하면 렌더링 또한 빨리 될 줄 알았습니다. 하지만 아래 이미지처럼 렌더링될 때 오래 걸렸고 저번 ForEach처럼 제대로 알지 못하고 사용한 것 같아서 이번 글에서는 LazyVStack에 대해서 알아보겠습니다.

LazyVStack은 하위 뷰들을 수직 방향으로 자라게 배열하고 필요한 만큼만 아이템을 만드는 뷰입니다.

VStack과 비슷하지만 필요한 만큼만 아이템을 만드는 뷰라는 점이 차이점입니다. VStack은 하위 뷰들이 한 번에 모두 렌더링 되며 이는 화면에 안 보이는 뷰도 포함됩니다. 하지만 LazyVStack의 경우 하위 뷰들 중에서 화면에 보이는 뷰들만 렌더링되며 안 보이는 뷰들은 지연 로딩 메커니즘을 사용해 화면에 보일 때 렌더링됩니다.
아래는 순서대로 LazyVStack, VStack을 사용한 이미지입니다.


이미지처럼 LazyVStack을 사용한 경우가 처음 화면에 나타나는 시간이 더 빠르며 CPU 사용량 또한 LazyVStack을 사용한 경우 더 적게 사용합니다.

이처럼 LazyVStack을 사용하면 화면에 보이는 뷰들만 렌더링하니 데이터가 많아져도 문제가 없을건데 처음 이미지처럼 렌더링하는데 오래 걸리는 이유가 궁금해졌습니다.
LazyVStack은 화면에 보이는 항목만 렌더링하지만, SwiftUI가 초기화 과정에서 전체 항목을 설정하고, 각 항목의 크기를 파악해야 하므로, 초기 렌더링이 느려집니다. 즉, 화면에 표시될 때 렌더링을 하지만 초기화 때 부모 뷰의 크와 자식 뷰의 내용(예: 텍스트 길이, 이미지 크기 등)에 기반하여 레이아웃을 결정하는 시간이 걸리기 때문에 초기 렌더링 또한 늦어진 거였습니다.
초기화 과정에서 레이아웃을 결정하고 렌더링한다면 중간에 데이터가 추가되서 뷰의 크기가 늘어나면 어떻게 되는지 궁금해서 실험해봤습니다.

데이터가 추가되서 뷰의 크기가 늘어나도 다른 뷰와의 간격은 유지되며 스크롤 뷰는 맞춰 늘어납니다.
정리하자면 LazyVStack을 사용해도 뷰를 초기화할 때 레이아웃을 정하기 때문에 시간이 걸리며, 중간에 데이터를 변경해서 뷰의 크기가 변경되면 레이아웃도 그에 따라 변하게 되는거 같습니다.