[Flutter/Decoding Flutter] RenderObjects?!

작성 날짜:

최근 업데이트 날짜:

Decoding Flutter 유튜브 영상


Render Tree

Flutter가 Widget Tree를 만든다는 것은 아마 모두가 알 것이다. Widget Tree에 맞춰서 Element Tree를 만드는 것도 마찬가지다.

하지만 이 Widget TreeElement Tree 외에 Render Tree라는 트리가 있다는 것은 생소하다.

Render TreeRenderObject들로 이루어진 트리이며, Element Tree에 의해 만들어진다.

Rendering Layer

위는 Dart Framework의 구조이다. 이 중 Widget Layer는 많이 익숙하다. 하지만 바로 밑에 있는 Rendering Layer는 익숙하지 않다.

Rendering LayerRenderObject, 그리고 이와 관련된 클래스들을 다루는 레이어이다.

일반적으로 개발자는 직접 Rendering Layer에 접근하지 않는다. 그 대신 Widget LayerRendering Layer에 접근한다. 따라서 코드에서는 Rendering Layer가 다루는 RenderObject가 보이지 않는다.

하지만 RenderObject를 볼 수 있는 방법이 있다. Flutter InspectorRender Tree 탭에 들어가면 RenderObject가 보이는 것을 확인할 수 있다.

RenderObject

앞서 Render TreeRenderObject로 이루어진 트리, Rendering LayerRenderObject를 다루는 레이어라고 했다.

그렇다면 공통적으로 언급된 이 RenderObject는 무엇일까?

RenderObject는 레이아웃, 페인팅, 적중 테스트(hit testing), 접근성 등을 다루는 오브젝트이다. 여러 종류의 RenderObject가 있지만, 대부분의 경우에는 2차원 좌표를 사용하는 RenderBox가 사용된다.

RenderObject의 재사용

Element Tree는 매 프레임마다 Render TreeWidget Tree와 동기화시킨다. 만약 조금의 변화가 있을 때마다 새로운 RenderObject 사용해야 한다면 동기화 작업이 매우 오래 걸릴 것이다. 하지만 다행히 RenderObject는 재사용할 수 있다.

예를 들어, 특정 Widget의 색깔이 변한다면, 해당 Widget에 상응하는 기존 RenderObject가 재사용되며 다시 그려진다.

또한 위의 이미지처럼 특정 WidgetWidget Tree에서 없어진다면, 해당 Widget에 상응하는 Element 또한 Element Tree에서 분리되고, 마찬가지로 해당 Widget에 상응하는 RenderObjectRender Tree에서 분리된다. 그리고 분리된 Widget이 새로운 위치로 이동되면 ElementRenderObject 또한 그 위치로 이동하여 재사용된다.

Key의 중요성

앞서 말한 ElementRenderObject의 재사용을 위해서 Key가 필요하다. Widget이 어느 위치로 이동했는지를 알아내야 ElementRenderObject를 재사용할 수 있는데, Key가 이를 알려주기 때문이다.

A와 B라는 고유 Key를 가지는 두 개의 Widget이 스왑되는 상황이라고 해보자. 두 Widget의 위치가 바뀌었지만 A와 B라는 Key 덕분에 각 Widget 해당하는 Element가 무엇이었는지 알 수 있다. 따라서 해당 Key를 가진 Widget에 상응하는 Element를 가져와 재사용할 수 있게 된다. 또한 이미지에서는 RenderObject가 생략되었지만 RenderObject도 동일한 방법을 통해 재사용된다.

페인팅과 레이아웃 커스터마이즈

RenderObject를 직접 활용하여 Widget의 페인팅과 레이아웃을 커스터마이즈할 수 있다.

하지만 이 방법은 코드가 복잡하고 길어진다고 한다. 따라서 위젯을 사용하는 간단한 방법이 있는지 꼭 확인해야한다. 예를 들어 캔버스 위에 페인트하는 정도라면, 복잡하게 RenderObject를 활용할 필요 없이 CustomPaint 위젯을 사용해서 간단하게 해결할 수 있다.

댓글남기기