
build()에서 return한 Widget은 Widget tree 로 간다

MyApp 클래스에서의 build()에서는 MaterialApp을 리턴하고, HomeScreen()의 build()에서는 Scaffold 를 리턴하고 있다
build 함수에서 리턴한 위젯은 위젯트리로 들어가는데, 이 위젯 트리의 root node는 MyApp 이다
build() 메소드의 리턴 결과는 build()를 실행할 당시에 있던 노드의 subtree로 들어간다MyApp.build 메소드 실행 이후에는, MaterialApp 노드가 child로 생기게 되고, MaterialApp.build 메소드 실행 이후에는 HomeScreen 노드가 child로 생긴다
즉, 위젯을 만들 때 넘겨준 파라미터의 이름이 child 이였으므로, 하위 위젯이 return 으로 상위 위젯에게 넘겨주면, 하위 위젯이 상위 위젯의 child 노드가 되는 것이다
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Row(
children: [
Image.network('https://www.example.com/1.png'),
const Text('A'),
],
),
코드에 보이는 widget은 Container와 Row 2개이지만, 플러터로 build() 메소드를 실행하면 subtree에 다른 widget이 추가로 들어가있다

위의 상황처럼, widget 하나를 그려도 플러터 내부적으로 사용하는 추가적인 widget이 widget tree에 들어가게 될 수 있다
위젯에서 화면에 그려질 방식들을 지정하면, 플러터는 실제로 그려질 instance를 만들게 되는게 이것이 element 이다
mount, update, performRebuild 등 메소드 존재함element tree의 노드와 widget tree의 노드는 모두 1:1 대응이다
Element tree의 루트 노드인 `ComponentElement`는 Widget tree의 루트 노드인 `Container`와 대응되고, 그 아래의 `RenderObjectElement`는 `ColoredBox`에 대응된다
ComponentElement : 다른 element의 host 역할을 함으로써 대장역할이다. 플러터가 실제로 화면을 그릴 때 이 종류의 element는 참고하지 않는다RenderObjectElement : 실제로 화면에 그릴 때 플러터가 참고하는 element이다. 
Element tree 는 widget tree와 RenderObject tree를 모두 참조한다.
즉, widget이 변한 경우 해당 변화를 감지하고 renderObject를 바꿀지말지 결정하는 것이다
모든 위젯은 widget.buildContext를 통해 자신과 연결된 element에 접근가능하다
buildContext 안에는 자신이 widet tree에 어떤 노드에 위치하는지 알려주는 정보가 있기 때문이다
build() 함수에서 계속 넘겨주는 (BuildContext context) 의 context에서 현재 노드의 위치정보를 가지고 있다showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
...
);
Dialog를 띄울 때에도 현재 rendering 된 화면 위에 Dialog의 배경과 UI를 추가로 그린다는 것이므로, 현재 rendering 된 화면이 해당 앱의 트리에서 어디에 위치하는지 알아야 한다
트리 상에서의 위치정보를 context 가 가지고 있으므로 build() 함수에서 context 계속 넘겨준 것이었다
✏️ 개발자는 widget code를 작성하고, 플러터는 개발자의 widget code를 보고 element 를 만든다. element에는 2가지 종류가 있으며, host 역할인 element 말고 다른 element가 직접적으로 Rendering 에 관여를 한다
플러터가 마지막으로 만드는 트리로, renderObject tree는 element tree를 참고하여 만들어진다

Layout 단계에서는 render tree를 참고하면서 최종적으로 widget이 어느 위치에 그려질지 결정된다
Expended, Flexible 등의 위젯들이 widget의 최상단에 감싸지는 이유이다child 도 widget의 상단에 위치하는 이유이다Layout 단계는 루트 노드부터 리프노드까지 내려가면서 Constraint 에 대한 정보만 확인한다 (예를 들어, size, position 등)
parent 노드로부터 제약 조건을 받은 child 노드는 해당 정보를 바탕으로 모양과 사이즈만 결정한다. 결정된 모양 및 사이즈 등의 정보를 다시 위쪽으로 올려보낸다. 이러한 정보만 오가는 것이 layout 의 작업이다.
Layout 의 작업이 끝나면 이제서야 화면에 그리는 paint 단계에 들어가게 되는 것이다
즉, 제한조건을 내려보내고, 사이즈를 올려보낸다 !!
플러터의 layout 작업은 1개의 frame 당 1번 일어난다
즉, 초당 60 frame을 지원하므로 초당 60번의 layout 작업이 일어나고 있는 것이다
🤓 Broccolism 님의 velog
https://velog.io/@broccolism/Flutter-%EC%9D%B4-%EC%BD%94%EB%93%9C..-%ED%99%94%EB%A9%B4%EC%97%90-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A0%A4%EC%A7%88%EA%B9%8C-1.-%ED%8A%B8%EB%A6%AC
와~~ 그림은 직접 그리신건가요?