Study/Dart,Flutter

14. [Flutter] 플러터 성능향상을 위한 꿀팁(1부 widget tree)

코딩 잘 할거얌:) 2022. 8. 20. 15:30
반응형

플러터를 시작한 지 얼마 되지 않았지만, 그래도 플러터 하시는 분들을 위해서 도움이 많이 되었던 팁들을 적어보자 한다. 그리고 꿀팁과 그 후속작으로는 자주 쓰는 패키지들을 적어보고자 한다.

 

음 맛있다~!


버전 정보

 

 

Flutter 3.0.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision f1875 d570 e (5 weeks ago) • 2022-07-13 11:24:16 -0700
Engine • revision e85ea0e79c
Tools • Dart 2.17.6 • DevTools 2.12.2

 


들어가기 전

 

이 글은 Flutter의 생명주기와 statelessWidget, statefulWidget을 기본적으로 안다면 좀 더 수월하게 이해할 수 있습니다. 

 

https://pcseob.tistory.com/17

 

6. Flutter의 Widget과 State 그리고 StatelessWidget과 StatefulWidget

앞서 포스팅에서는 Dart언어의 비동기식을 알아보았다. 이번에는 Dart의 가장 유명한 프레임워크이자 크로스 플랫폼인 Flutter의 State에 관해서 자세하게 알아보자. 오늘도 어김없이(재미없는) 이론

pcseob.tistory.com

 

 

 

https://pcseob.tistory.com/18

 

7. StatefulWidget의 LifeCycle(생명주기) 그리고 setState

이전 포스팅은 state와 widget 그리고 statelessWidget에 대해서 알아보았다. 이번에는 statefulWidget과 상태 관리(state management)에 관해서 알아보도록 하자. 오늘도 어김없이 이론이다. 하지만 이번에는 굉.

pcseob.tistory.com


 

 

Everything is a Widget

 

 

Flutter는 모든 것이 위젯으로 되어있다 해도 무방하다. 우리가 흔히 보는 Container, Scaffold, StatelessWidget, StatefulWidget 이 모든 건 위젯이다. 위젯들로 화면을 구성하게 된다.

 

https://docs.flutter.dev/development/ui/widgets-intro

 

Introduction to widgets

Learn about Flutter's widgets.

docs.flutter.dev

 

그래서 Flutter를 처음 시작하실 때 '모든 건 위젯이다.' 라고 생각하시면 좋다. 이 말은 return 타입을 Widget으로 맞추면 웬만큼 다 맞다는 뜻이기도 하다.

만능 위젯 Container, 세로로 쌓는 Column, 텍스트 출력을 위한 Text 그리고 목록을 위한 Listview까지 모든건 Widget으로 되어있다. 이 사실을 반드시 기억하시고 다음 내용으로 넘어가 보자.

 

 

Widget Tree

 

 

플러터는 화면을 그리기 위해서 여러 가지 과정을 거치는데 그중 3가지 트리를 가지게 된다.

 

  • Widget Tree  
  • Element Tree
  • Render Tree

이 세 가지 트리를 가지게 된다.

Element Tree와 Render Tree를 간단하게 설명하자면, Element Tree는 Widget들에 1:1 매칭 되는 데이터라고 할 수 있다. 그리고 우리가 자주 보는 BuildContext들이 모여서 Element Tree가 된다.

Render Tree는 말 그대로 랜더링 할 때 화면상 표현된 Tree이다. 

 

자 이제 Widget Tree는 무엇일까? 말 그대로 Widget들이 어떻게 연결되어있는지 보여주는 나무이다. 이게 왜 중요하냐면 Flutter를 개발할 때 성능과 직결되는 문제이기 때문에 알아야 한다.

 

 

출처 : https://www.fluttercampus.com/tutorial/5/flutter-widgets/

우리가 화면을 생성하면 Widget tree는 이렇게 생성이 된다. Main에 시작하는 MyApp에서 Text까지 빠짐없이 생성이 된다. 만약에 우리가 'Column아래에 있는 Text를 변경하고 싶다면 어디서부터 새로 화면을 새 로고 쳐야 하냐?'에서 성능 차이가 생기게 된다. 

 

화면을 업데이트하는데 StatefulWIdget의 setState를 활용한다고 한다면, 어디에 달아주어야 할까? 가장 좋은 방법은 Text만 변경하는 것이다. 위의 위젯 트리와 비슷하게 예시 코드를 짜 보았다. 

 

파란줄이 뜨는 linter도 설명하겠다.

현재 scaffold에 있는 FloatingActionButton을 누르면 화면이 업데이트된다는 코드이다. 플로팅 버튼을 누르게 된다면, 'Update Widget Tree Text'로 바뀌게 될 것이다. 근데 과연 이 Text만 변경이 된 것일까?

정답은 당연히 아니다. 

setState는 현재 자기가 소속되어있는 Widget 그러니까 StatefulWidget을 업데이트하는 역할을 한다. 그러니까 Build부분을 새로 그린 다는 뜻이다. 변경이 되지 않아서 우리가 눈치채지는 못했지만, Appbar, Widget Tree 1이라고 적혀있는 Text 그리고 FloatingActionButton까지 모두 새로 빌드가 된다는 뜻이다.

 

그렇다면 우리는 Text만 업데이트하려면 어떻게 해야 할까? 두 가지 방법이 있다.

 

  • 변경되는 위젯을 제외한 변경되지 않는 위젯에 모두 const를 붙이는 방법
  • 변경되는 위젯을 새로운 위젯으로 생성하는 법

우선 모두 const를 붙이는 방법은 위의 코드에서 파란색 라인(linter)이 생긴 걸 볼 수 있다. 저 부분들은 flutter에서 '이 위젯은 변경되지 않을 거 같은데, const를 붙여서 재 빌드되는 거 막는 게 어때?'라고 제안하는 것이다. dart언어에서 const는 컴파일 타임 시점에 이미 결정을 해버리는 거다. 간단하게 말하자면 화면이 그려지기도 전에 정해버려서 바꾸지 못하게 막는다는 거다. 그러면 const 붙은 위젯들은 한번 빌드되고 업데이트 때문에 재 빌드되는 시점에도 다시 그려지지 않고 유지가 된다는 뜻이다. 

이 방법은 사실 완벽한 해결책은 아니다. 업데이트 위젯'만' 업데이트하는 방법은 아니기 때문이다. 성능이 개선이 되겠지만.

 

const를 붙이고 쓸모없는 위젯은 제거한 모습 linter가 모두 사라졌다.

 

두 번째 변경되는 위젯을 새로운 위젯으로 생성하는 방법이다. 생각보다 간단하다. 

GlobalKey에 관해서는 다음에 포스팅하겠다. 아주 간단하게 말하자면, key가 적용된 widget의 상태들을 제어할 수 있게 해 주는 것이라고 생각하면 좋다.

내가 사용하는 위젯을 statefulwidget으로 빼서 widget tree를 빼내는 것이다. FloatingActionButton을 눌러서 UpdateText의 텍스트를 변경한다면 HomePage의 화면 전체가 새롭게 다시 그려지는 것이 아닌 UpdateText만 새로 그려지게 되어 성능개선이 이루어지게 된다.

 

 

 

요약하자면 성능 향상을 위해서는 재 빌드되는 위젯과 그렇지 않은 위젯을 분류하여 wiget tree를 따로 빼는 것이 좋다.


오류, 지적사항 그리고 궁금한 것은 댓글 부탁드립니다.

728x90