728x90
반응형

 

🔥 Flutter 핵심 개념 정리: 위젯·엘리먼트·렌더오브젝트 완전 이해하기

 

Flutter를 공부하다 보면 꼭 이해해야 하는 3가지 개념이 있다.

 

👉 Widget

👉 Element

👉 RenderObject

 

처음에는 모두 비슷해 보이지만, Flutter의 UI 렌더링 구조를 정확히 이해하려면 이 세 가지가 어떤 역할을 하는지 명확하게 구분할 필요가 있다.

 

이 글에서는

위젯 → 엘리먼트 → 렌더오브젝트의 흐름

가장 쉬운 비유와 실제 예시, 그리고 트리 구조로 이해할 수 있도록 설명한다.

 


 

1. Widget — UI의 “설계도”

 

Widget은 UI가 어떻게 보여야 하는지 정의하는 ‘설계도’이다.

 

  • 불변(immutable)
  • 화면의 실제 위치나 크기 정보 없음
  • 단순히 “이런 모습으로 만들어줘!” 라는 데이터 덩어리

 

예를 들어, 아래 코드는 모두 “위젯”이다.

Center()
Padding(padding: ...)
Column()
Text("Hello")
Icon(Icons.star)

하지만 이 위젯들은 실제로 화면에 그려지지 않는다.

설계도이기 때문이다.

 


 

2. Element — 위젯의 “실제 위치 정보”

 

Element는 위젯의 인스턴스이자,

UI 트리에서 ‘현재 위젯이 어디에 존재하는지’를 나타내는 객체이다.

 

즉,

 

  • 위젯이 어디에 붙어 있는지 (부모/자식 관계)
  • 위젯이 가진 상태(State)
  • 위젯의 생명주기

 

등은 모두 Element가 관리한다.

 

 

BuildContext의 정체 = Element

 

위젯의 build() 메서드에서 받는 BuildContext context

사실 해당 위젯의 Element 자신을 가리키는 참조이다.

 

예:

@override
Widget build(BuildContext context) {
  // context = 이 위젯의 Element
}

그래서 context를 통해

 

  • Theme.of(context)
  • Navigator.of(context)
  • MediaQuery.of(context)

 

처럼 조상 위젯이나 환경 정보에 접근할 수 있는 것이다.

 

 

모든 위젯은 각각 고유한 Element를 가진다

 

PostEmptyView, Center, Padding, Column, Text, Icon…

모두 각각의 Element를 갖는다.

 


 

3. RenderObject — 실제로 그리는 “엔진 객체”

 

RenderObject는 Flutter 엔진과 직접 연결되어

실제 화면에 그림을 그리는 역할을 한다.

 

RenderObject의 역할은 다음과 같다.

 

  • 레이아웃 계산 (size, position)
  • 페인팅 (draw)
  • Hit Test (터치 이벤트 전달)
  • 스크롤, 정렬, 배치 등 물리적 동작

 

예:

 

  • Text → RenderParagraph
  • Column → RenderFlex
  • SizedBox → RenderConstrainedBox

 

RenderObject는 UI를 실제로 구성하는 “진짜 물체(knob, pixel)”이다.

 


 

4. 세 가지의 관계를 한 번에 이해하기

 

정리하면 이렇게 흐른다:

Widget (설계도)
   ↓ createElement()
Element (위치 + 상태 + 트리 정보)
   ↓ createRenderObject()
RenderObject (레이아웃 + 그리기)

 

비유하면?

개념비유역할

Widget 집의 설계도 UI 구조 정의
Element 실제 방의 위치 위젯이 트리에서 어디 있는지 저장
RenderObject 집의 벽/창문 실제 화면에 그려짐

 


 

5. 트리로 보면 더 명확해진다

 

아래 예시를 보자.

PostEmptyView
 └─ Center
      └─ Padding
           └─ Column
                ├─ Icon
                ├─ SizedBox
                ├─ Text
                ├─ SizedBox
                └─ Text

이건 위젯 트리다.

Flutter는 이 위젯 트리를 기반으로 동일한 구조의 Element 트리를 생성하고,

그 Element에서 필요한 것들만 RenderObject 트리를 만든다.

 


 

6. Rebuild 과정에서는 무엇이 재사용될까?

 

Flutter가 성능이 빠른 이유는

모든 것을 새로 만드는 것이 아니라 필요한 것만 업데이트하기 때문이다.

구분상태설명

Widget 매번 새로 생성됨 가벼운 데이터 객체라 부담 없음
Element 재사용됨 (트리 유지) 트리 구조와 State 유지
RenderObject 대부분 재사용됨 속성 변경만 업데이트

이 구조 덕분에 Flutter는 빠르게 rebuild가 가능하다.

 


 

7. BuildContext는 “최상위”가 아니다

 

많은 초보자들이 오해하는 부분이 있다.

 

BuildContext는 “해당 위젯의 위치(Element)”를 의미한다.

 

 

  • PostEmptyView build() 안에서는 PostEmptyView의 context
  • Column 내부 Builder에서는 Column 내부의 context
  • Text 내부에서는 TextElement의 context

 

따라서 위젯마다 각자의 BuildContext(Element)가 존재한다.

“최상위 context 하나만 존재하는 구조”가 아니다.

 


 

8. 정리: 한 장으로 끝내는 개념 총정리

📘 Widget
- UI 정의 (설계도)
- 불변
- 위치 정보 없음

🧩 Element
- 위젯의 실제 인스턴스
- 트리의 구조 담당 (부모/자식)
- 상태(State) 보관
- BuildContext의 정체

🎥 RenderObject
- 화면에 실제로 그리는 객체
- 레이아웃 / 그리기 엔진
- 필요한 위젯에서만 생성됨

 


 

마무리

 

Flutter의 핵심 구조는

Widget → Element → RenderObject

이 세 가지가 어떻게 협력하느냐를 이해하는 것이다.

 

이 원리를 제대로 이해하면:

 

✔ Flutter 렌더링 구조가 명확해지고

✔ BuildContext의 역할이 분명해지고

✔ Rebuild / Layout / Render 단계가 잡히며

✔ 성능 최적화까지 자연스럽게 이해된다.

728x90
반응형

+ Recent posts