신입 개발자에서 시니어 개발자가 되기까지

React Virtual DOM(feat. 브라우저 렌더링 프로세스) 본문

javascript/React Js

React Virtual DOM(feat. 브라우저 렌더링 프로세스)

Jin.K 2022. 11. 17. 00:32

1. 브라우저 렌더링 프로세스

1) 렌더링 순서

    - DOM tree 생성 -> CSSOM 생성 -> render Tree 생성 -> layout(배치, flow) -> painting -> Display
    - display가 완료된 상태에서 DOM 조작하면 render tree를 수정하고 layout - painting 단계를 다시 거친다.

2) Layout

    a. DOM 노드의 레이아웃이 변경될 때 변경 후 영향을 받는 모든 노드를 다시 계산하고 렌더트리를 재생성한다.
    b. 강제로 reflow를 일으키는 api
        - 참고 : https://gist.github.com/paulirish/5d52fb081b3570c81e3a
        - 대표적으로 innerText, scrollXY, scrollTo, focus(), offsetXY
    c. 페이지 렌더링 성능 확인 방법
        -개발자 도구 perfomance 탭에서 녹화

3) Repaint

    - 레이아웃 수치는 변경하지 않고 style만 변경한다면 reflow가 일어나지 않는다. repaint만 일어난다.
    - 여기서 레이아웃 수치란 스크린에 지정된 좌표다.
    - https://saiki.hashnode.dev/the-one-thing-that-no-one-properly-explains-about-react-why-virtual-dom

4) Reflow, Repaint 최적화

        i. 부드러운 애니메이션은 성능 저하를 일으킨다.
        ii. 애니메이션이 들어가면 position을 fixed나 absolute로.
        iii. 참고: https://github.com/im-d-team/Dev-Docs/blob/master/Performance/Reflow%20Repaint.md

2. virtual DOM

1) 개념

    - 메모리에 존재하는 가상 DOM

2) 작동 원리

    i. 메모리에 virtual DOM을 가지고 있다가 view의 변화를 감지하면 virtual DOM을 1차적으로 변화시킨다.
        - Real DOM에 바로 적용하면 rendering process의 일부분을 매번 발생시키지만, 모아서 한번에 하면 렌더링 프로세스를 한 번만 발생시킨다.
        - 이러한 개념은 react에만 있는 것이 아니다. Document fragment로 DOM을 조작하는 것도 이런 개념과 비슷하다.
            □ https://developer.mozilla.org/ko/docs/Web/API/Document/createDocumentFragment
            □ creeateDocumentFragment 생성 후 추가할 요소 여기에 모아서 한번에 부모태그에 appendChild 하는 개념
        - 리액트는 이 작업을 자동으로 해주는 것.        
    ii. Reconciliation
        - virtual DOM과 DOM을 비교해 DOM을 갱신하는 작업. 대부분 작업은 배치(batch) 처리로 실행된다.
    iii. 이 과정에서 key를 사용하면 효율적으로 렌더링이 된다.
    iv. 비교 알고리즘
        - 참고 : https://reactjs.org/docs/reconciliation.html
        - 비교 알고리즘의 복잡도는 O(n^3)
        - 리액트는 휴리스틱 기법으로 비교한다. 두 가지 가정이 있음.
            (1) 비교하는 두 요소의 타입이 다르면 바로 다른 tree를 생성한다.
            (2) key로 어떤 요소를 바꾸지 않을지 결정할 수 있다.(key 다르면 바꾼다는 의미인 듯)
    v. 갱신방법
        - 대표적으로 setState(), redux에서 store 변경 시 갱신된다. state를 변경하면 ReactUpdates.enqueueUpdate()를
        실행해서 변경 대상 컴포넌트로 등록하고, 배치작업 시 이를 실제로 갱신한다. 화면의 변화가 일어나는 것은 갱신할
        때 변화가 일어난다.
    vi. key prop을 정의해야하는 이유
        https://github.com/im-d-team/Dev-Docs/blob/master/React/Virtual%20DOM.md