플러터는 어떻게 동작하는 가

아마도 플러터를 사용하는 사람들은 이러한 경험이 있을 것입니다.

Stateful Widget에 분명히 데이터를 처리하여 호출하였는데 화면에 보이지 않거나 이상하게 동작하네?

만약 Stateful Widget만 쓰는 강의 튜토리얼에서만 쓰이는 간단한 형태의 페이지라면 문제가 될 것은 없습니다. 하지만 Stateless, Stateful, 그리고 Provider / GetX / Bloc 과 같은 상태관리 패키지들을 섞어 사용하게 된다면 상당히 혼란스러운 경험을 하게 될 수 있습니다.

제대로 플러터 동작원리를 모르고 많은 기능을 사용하여 어플리케이션을 만든다면 엄청난 비효율이 발생해서 자원을 잡아먹거나 아니면 아얘 어플리케이션이 제대로 동작하지 않는 경우가 생길 수 있습니다.

따라서 일단 플러터의 동작원리를 정확히 이해해야 합니다.

그렇다면 플러터는 어떻게 동작을 할까요

우선 우리는 플러터의 Build 함수가 자주 실행되는 것을 압니다.
하지만 빌드가 60fps로 화면에 UI가 그려질 때 마다 호출 되는 것은 아닙니다.
빌드는 한번만 호출되고 화면에는 계속 그려질 수 있는 것이죠.
하지만 만약에 1초에 60번 위젯을 다시 빌드를 해야한다면 그건 어플리케이션에 상당한 부담이 됩니다.

그렇다면 빌드가 진짜로 하는 일이 무엇일까요

플러터는 세가지 트리로 구성되어있습니다.

위젯트리

  • 위젯은 설정 정보를 담고있다. 그리고 자주 빌드된다.
  • 빌드될 때 위젯의 설정 정보가 바뀌는 것이 아니라 새로운 정보가 생성되고
    기존의 위젯트리의 위젯은 폐기되고 가비지 콜렉터가 메모리에서 해제 시킨다.
  • 위젯은 변경불가(Immutable)하다.

엘리먼트 트리

  • 다시 빌드되지않는다 빌드를 호출한다고 해도…
  • State, Render Object, Widget에 대한 주소를 갖고 있다.

렌더트리

  • 화면상에 보여지는 것이지만 다시 리빌드되는 경우는 거의 없다.
  • 화면에 엘리먼트를 통해 위젯의 정보를 가지고 60fps로 UI를 화면에 그린다.

플러터가 엘리먼트가 없는 위젯을 만나면 엘리먼트를 생성합니다.
엘리먼트란 플러터에 의해 메모리에 올라가는 위젯에 대한 정보를 가진 객체입니다.
엘리먼트는 그 자체로는 어떤 정보가 없고 단지 위젯을 포인팅히기만 합니다.

State는 위젯에서 create state 명령어로 독립적으로 메모리에 생성됩니다.
그리고 엘리먼트는 위젯정보를 가지는 것과 마찬가지로 State 정보를 가지게 됩니다.
그리고 State는 재생성되지 않고 단지 내용만 업데이트 됩니다.

그러면 엘리먼트는 그냥 위젯과 State 뿐만 아니라 렌더 오브젝트를 가르키기도한다.

그래서 플러터 엔진이 만약 엘리먼트가 렌더 오브젝트를 가리키지 않는경우

엘리먼트를 통해 위젯의 Configuration읽어오고

여러가지 페이즈를 통과한 뒤 렌더 오브젝트를 생성하여 가리키게 만든다.

setState()가 호출되면 그 Stateful Widget은 Dirty하다고 마크가 됩니다.
그리고 State를 업데이트 하고 Stateful Widget 하위 위젯들까지 전부 다 재생성합니다. 그리고 다시 Element들과 새로 생긴 위젯들을 연결하고 기존의 위젯들을 폐기합니다. 비효율적이라고 생각 할 수도 있는데 하지만 이것은 플러터의 강제사항이라서 모두 위젯들을 다시 만드는 게 맘에 안든다고 해서 어떻게 할 수 없습니다. 단지 위젯 앞에 const를 붙일 수 있는 위젯들은 붙여서 다시 빌드하지 않는 선택이 있긴 있습니다.

따라서 빌드를 한 두번 더 한다고 아니면 덜 한다고 해서 성능의 변화폭이 크지 않습니다. 애초에 플러터가 잦은 위젯 빌드를 염두를 해둔 설계이고, 엘리먼트 트리와 렌더 트리는 다시 리빌드 되지 않아서 위젯 빌드를 많이 한다고 해서 성능하락이 많지는 않기 때문입니다. 하지만 앞서 말씀드린것과 같이 1초에 60번정도 다시 빌드를 한다면 문제가 생기겠죠..

따라서 기본적인 개발습관으로
위젯을 만들 때 이 위젯이 얼마나 자주 빌드될 지 염두를 해두면서 페이지를 구성해야합니다. 자주 빌드되는 위젯은 하위에 두고 자주 빌드되지 않는 부분은 상위 위젯트리에 구성을 해야합니다.

profile
취준생입니다.

0개의 댓글