티스토리 뷰

flutter

How Flutter renders Widget

길 킴 2019. 11. 23. 23:50
728x90

Flutter는 Google의 UI Tool kit으로 웹, 모바일, 데탑을 아름답게 만들게 해준다. 

먼저, 아주 간단한 UI 구성의 코드를 보자. 

1. 2개의 Widget으로 구성된 예시 



2. 3개의 Widget으로 구성된 예시 

 

Flutter의 모든것은 Widget이다. 

그리고 Widget은 immutable 하다. 

 

Flutter의 렌더링 과정은 3개의 트리 구조이다.  

1. Widget 2. Element 3. RenderObject

  Widget Element RenderObject

Docs 설명

Widget은 Element의 설정을 설명한다. 
(Widget: describes the configuration for an Element)

Element는 Widget의 인스턴스이다. (it's an instantiation of those widgets)

또한 Widget의 Lifecycle을 관리한다. 

RenderObject들의 tree 구조가 있고, 배치하고 UI에 그리는 역할을 한다. 

Flutter가 UI를 그릴 때, Widget 트리가 아닌 RenderObject 트리를 바라본다. 

기능으로 설명

Configure

사용자가 Widget 코드를 작성하고,
property, value등을 지정한다. 

widget tree의 완성

Life Cycle

UI의 전체적인 lifecycle을 매니징한다. 
UI hierarchty의 요소를 구성하고 element를 관리 구성한다. 

Paint

그린다. 

정리하자면, Widget이 구성하고, Element가 매니징하고, RenderObject가 그린다. 


좀 더 쉬운 예제를 들어가보자 

한개의 Wiget

Widget Element RenderObject

Flutter가 앱을 시작하면, runApp() 함수를 호출한다. 

Tree의 Root에 Widget을 추가한다. 

Flutter는 Widget에게 Element를 생성할 것이냐고 묻는다. 그게 LeafRenderObjectElement() 함수이다. 

Tree의 Leaf(잎) 이기 때문에 그리 불린다.  

 

Element에게 RenderObject를 생성할꺼냐고 묻는다.

 그 다음엔 Widget은 Paint하기 위한 모든 속성값을 전달한다. 

 

 


Widget에서 어떤 변화가 일어난다면 무슨일이 일어날까요? 

runApp() 이 2번 들어가 있다. 

이미 렌더링을 다 끝냈는데, 다른 위젯으로 변경하게 되면 어떻게 될까

바로 canUpdate() 메서드를 주목해보자.

 두 Widget의 Runtime 시의 타입은 같니? => RichText로 같다. 
그리고 위의 예제는 Widget의 KEY를 사용하지 않으니까 상관없다.

결론은 canUpdate() 함수에서 true를 Return한다. 

Old Widget을 지우고 계층 트리에 다시 꽃아 넣는다. 

configuration 이 바뀌었을 테니 뭔가를 해야한다. 

Element는 updateRenderObject() 함수를 호출한다. 


multiple widget이 있는 경우에는 어떻게 되나요? 

SingleChildRenderObjectElement: Widget이 하나의 child 만 가지고 있을 때 호출하는 함수


2개의 Widget을 가지고 runApp() 을 두번 실행할 때는 어떻게 될까? 

Flutter 왈:  2개의 Center Widget, 그리고 같은 런타임에 도니까 재사용 할 수 있겠군. RichText도 마찬가지겠어!

그래서 결국은 이거다. 


그럼 2개 이상의 Widget의 경우는 어떻게 되나요?


더 복잡한 예제를 볼까요? 

하단에 'Switch free' 라는 버튼을 누르면 'Hello Flutter' 부분이 변하는 예제가 있습니다. 

 

하나의 Button과 2개의 Tree를 가진 하나의 StatefulWidget 을 가진 코드입니다. 

Android Studio 에서 Dart DevTools 를 이용해서 아래와 같이 Tree 구조를 볼 수 있다. 

위의 코드의 경우에는 두개의 Tree의 Widget 구조가 똑같기 때문에 RenderObject 도 똑같을 거라 예상할 수 있다. 

Dart DevTools 에서 RichText와 SizedBox의 RenderObject id 값을 알아낼 수 있다. 
'switch tree' 버튼을 눌러서 텍스트 내용을 변경할때, RenderObject id 값은 같은걸 확인할 수 있습니다. 


RenderObject의 id값이 바뀌는 경우를 살펴보자. 

위의 코드중에 secondTree의 Widget중 SizedBox를 Padding 으로 변경해보자. 

id값들을 비교해보면 RichText는 그대로이고, Padding은 새로 생겨났으니 새로운 id값이 부여되어 있다. 
위에서 설명한 canUpdate() 함수를 가지고 판단해보자. 
Runtime type이 SizedBox에서 Padding 으로 변경되었으니, canUpdate() 메서드는 FALASE 를 리턴한다. 
Flutter 는 이전에 없던 위젯이 생겼으니 Padding Widget을 새롭게 Create 한다. 

그렇다면,  firstTree에서 사용하던 SizedBox의 id는 바뀌었을까? 
=> completely different RendeObject!
Padding에서 SizedBox로 바뀌게 되면, firstTree에서는 Padding Widget은 필요없기 때문에 Destroy 시킨다. 


이것이 바로 위에서 설명한 Widget, Element, RenderObject 의 3가지가 필요한 이유이다. 

다시 정리하자면 Widget 은 당신이 작성한 코드를 가지고 UI 를 구성한다. 
Element는 계층간의 관계속에서 잘 돌아가도록 관리하고, Widget이 효율적으로 바뀌거나 사라지도록 한다.  
RenderObject가 최종적으로 그린다. 

 


출처: https://www.youtube.com/watch?v=996ZgFRENMs

'flutter' 카테고리의 다른 글

Provider 라이브러리 사용  (0) 2020.02.23
Mac에 Fultter로 Android 개발하기 - 2  (0) 2019.10.18
Mac에 Fultter로 Android 개발하기 - 1  (0) 2019.10.18
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함