노드 트리 구축 시 성능
트리를 하향식으로 작성하는 것과 상향식으로 작성하는 것에는 중요한 차이점이 있다.
Compose로 표현하려는 그래프에 노드가 삽입될 때마다 노드의 모든 상위 항목에 알려야 한다고 가정해 보자.
하향식 삽입의 경우엔 부모의 부모 노드, 조상 노드 등 수많은 노드에 알려야 할 수 있다.
그 수는 그래프에 새로운 깊이(depth)가 추가될 때마다 변경 사항을 알려야 할 노드가 기하급수로 증가한다.
반면 상향식 삽입의 경우엔 부모가 트리에 바로 연결되지 않는 특징덕에 자신의 직속 부모에게만 변경사항을 알리면 된다.
만약 자식 노드에게만 변화를 알리는 형태의 전략을 취한다면 노드의 변화를 알리기 위한 비용을 많이 절감할 수 있다.
따라서 전략은 표현하고 있는 트리에 따라가거나 변경 사항들이 트리의 위쪽이나 아래쪽에 어떻게 알려져야 하는지에 따라 달라질 수 있다.
변경 사항이 적용되는 방식
클라이언트단의 Compose 라이브러리들은 Applier 인터페이스를 구체화하며, 그중 하나가 Android UI에서 사용되는 UiApplier이다.
UiApplier는 ‘노드 적용’의 의미를 내포하며, 특정 유즈 케이스에 대해 우리가 스크린에서 보는 컴포넌트가 어떻게 생성되는지 알아볼 수 있다.
internal class UiApplier(
root: LayoutNode
): AbstractApplier<LayoutNode>(root) {
override fun insertTopDown(index: Int, instance: LayoutNode) {
}
override fun insertBottomUp(index: Int, instance: LayoutNode) {
current.insertAt(index, instance)
}
override fun remove(index: Int, count: Int) {
current.removeAt(index, count)
}
override fun move(from: Int, to: Int, count: Int) {
current.move()
}
override fun onClear() {
root.removeAll()
}
override fun onEndChanges() {
super.onEndChanges()
(root.owner as? AndroidComposeView)?.clearInvalidObservations()
}
}
이전 글에서 봤던 Applier의 제네릭 타입 N이 LayoutNode로 변경되었다.
이는 렌더링 될 UI 노드를 나타내기 위해 Compose UI가 선택한 타입이다.
다음으로 주목해야 할 점은 AbstractApplier를 상속받은 형태인데, 방문한 노드를 스택에 저장하는 기본 구현체이다.
트리 하단에서 새 노드를 방문할 때마다 이를 스택에 추가하고, 방문자가 위로 이동할 때마다 마지막으로 방문한 노드를 스택의 상단에서 제거한다.
이는 일반적으로 여러 Applier 간에 공통적으로 사용되는 스펙이기에 추상 클래스로 만들어졌다.
또한 Android에선 노드 삽입이 상향식으로만 수행되기 때문에 새 하위 항목이 삽입될 때마다 중복되는 노드 알림을 방지하기 위해 상향식 전략이 적합하다.
노드를 삽입, 제거, 이동하는 방법은 모두 노드 자체에 위임된다.
LayoutNode는 Compose UI가 UI노드를 모델링하는 방법으로 상위 노드와 하위 노드에 관한 모든 정보를 알 고 있다.
노드를 삽입하는 행위는 해당 노드를 주어진 위치의 새 부모 노드와 연결한다는 의미이고 노드를 제거하는 행위는 단순히 목록에서 해당 노드를 제거하는 것을 의미한다.
변경 사항이 끝나면 onEndChanges()를 호출할 수 있고, 이는 최종적인 요구사항을 루트 노드 사용자까지 위임한다.
이는 변경 사항을 적용하기 전에 항상 onBeginChanges()가 먼저 호출된다는 가정이므로, onEndChanges()는 마지막에 호출되어야 한다.
'Android' 카테고리의 다른 글
[Android] Compose 런타임 - (10) (0) | 2024.12.09 |
---|---|
[Android] Compose 런타임 - (9) (0) | 2024.12.05 |
[Android] Compose 런타임 - (7) (0) | 2024.12.03 |
[Android] Compose 런타임 - (6) (0) | 2024.12.02 |
[Android] Compose 런타임 - (5) (0) | 2024.11.29 |