위젯의 트리 구조
대부분의 앱의 화면은 위젯을 여러 개 조합해서 구성합니다. 그런데 한 화면을 구성하는 모든 위젯을 단일 트리 구조를 이룹니다.
화면을 구성하는 3개 트리 구조
앞에서 위젯의 트리 구조를 알아봤는데 사실 플러터 프레임워크가 화면을 만들 때 2개의 트리 구조를 더 만듭니다. 바로 엘리먼트 트리와 렌더 트리 입니다. 개발자는 위젯을 작성해야 하므로 위젯 트리마 알고 있으면 되지만, 프레임워크를 이해하는 차원으로 알아 두면 좋습니다.
앞에서 살펴봤듯이 위젯은 화면에 보일 뷰를 설명만 할 뿐 실제 화면에 출력할 대상은 아닙니다. 따라서 프레임워크에서 뷰 설명을 보고 위젯 트리를 참조해 실제 화면에 출력할 객체들을 별도의 트리 구조로 만듭니다. 예를 들어 위젯을 아래 처럼 구성했다고 가정해 보겠습니다.
// 위젯 구성 예
Center(
child: Column(
children: [
Text("Hello"),
Text("World")
],
)
)
실제 앱을 개발할 때는 이보다 많은 위젯으로 복잡하게 화면을 구성하므로 코드만 보고 전체 위젯의 트리를 파악하기는 쉽지 않습니다. 이때는 안드로이드 스튜디오의 플러터 인스펙터 도구를 이용하면 됩니다.
앞의 코드를 작성한 후 안드로이드 스튜디오의 오른쪽 사이드 바에 있는 [Flutter Inspector] 탭을 클릭하면 위젯의 트리 구조를 확인할 수 있습니다. 인스펙터 창에서 위젯 트리 영역에는 개발자가 작성한 위젯의 구조가 보이며, 이 가운데 하나를 클릭하면 위젯 상세 트리 영역에서 세부 정보를 확인할 수 있습니다.
코드에는 Center => Column => Text 위젯을 사용했지만 실제 위젯 트리에는 Text 하위에 RichText라는 위젯까지 있습니다. Text에서 RichText 위젯으로 화면에 출력할 문자열을 표현하기 때문입니다.
그리고 각 위젯의 상세 설명에서 어떤 위젯은 renderObject 정보를 가지고 있고 어떤 위젯은 가지고 있지 않습니다. 이 renderObject를 포함하는 위젯이 실제 화면에 그릴 정보를 가진 위젯입니다.
플러터 프레임워크는 이 위젯 트리를 기반으로 엘리먼트 트리를 만듭니다. 위젯 트리는 개발자가 작성하는 화면 구성 주문서라고 할 수 있습니다. 이 주문서를 보고 실제 화면을 구성하는 정보는 프레임워크 내부에서 엘리먼트 트리로 만듭니다. 위젯 객체 하나당 엘리먼트 객체를 하나씩 만들어 트리를 구성하며, 위젯보다는 더 상세한 정보가 담깁니다.
엘리먼트 트리는 ComponentElement와 RenderObjectElement 객체로 구성됩니다. ComponentElement 객체는 트리 구조에서 다른 객체를 포함하는 역할만 하며 화면에 출력할 정보를 가지지는 않습니다. 실제 화면에 출력할 정보는 RenderObjectElement에 담깁니다.
그런데 엘리먼트 트리의 객체도 실제 화면에 무언가를 출력하지는 않습니다. 단지 정보만 담고 있습니다. 이 엘리먼트 트리 정보를 바탕으로 실제 화면을 출력하는 렌더 트리가 만들어집니다. 렌더 트리의 객체는 위젯 트리와 직접 연계되지 않습니다. 또한 모든 엘리먼트 객체를 대상으로 렌더 트리의 객체가 하나씩 만들어지지 않고, 실제 화면에 출력할 정보를 가지는 RenderObjectElement에 해당하는 객체로만 구성됩니다.
렌더 트리를 구성하는 객체는 실제 화면 출력하는 객체입니다. 그림에서는 RenderObject로만 표현했지만 실제로는 RenderObject 타입으로 표현되는 RenderDecorateBox, RenderImage, RenderFlex 등 다양한 객체가 사용됩니다.
왜 이렇게 복잡한 트리 구조를 가지나요?
위젯 트리 외에 엘리먼트 트리, 렌더 트리 등이 존재하는 이유는 화면 렌더링(출력) 속도 때문입니다. 화면에 변경 사항이 발생할 때 얼마나 빨리 화면에 반영해 주는가는 프레임워크의 성능을 결정하는 중요한 요소입니다. 예를 들어 사용자가 버튼을 클릭하면 보통은 버튼의 배경색을 살짝 변경했다가 원복하는데, 이런 반응이 아예 없거나 1초 이상 걸린다면 어떨까요? 사용자는 매우 답답할 것입니다.
플러터는 네이티브 앱 수준의 성능을 목표로 합니다. 따라서 화면에 변화가 있을 때 최적의 알고리즘으로 변경할 부분만 다시 렌더링해서 빠르게 반영하도록 설계됐습니다. 이런 부분을 개발자가 신경쓰지 않게 하려고 위젯 트리 이외에 엘리먼트 트리, 렌더 트리가 존재하는 것입니다.
'Flutter' 카테고리의 다른 글
동적인 화면 만들기 (0) | 2024.11.15 |
---|---|
정적인 화면 만들기 (0) | 2024.11.15 |
화면을 구성하는 위젯 (0) | 2024.11.15 |
멤버를 공유하는 믹스인 (1) | 2024.11.15 |
추상 클래스와 인터페이스 (0) | 2024.11.15 |