ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 브라우저 렌더링 과정을 이해하려면 DOM을 알아야 한다?
    React 2023. 12. 20. 22:24

    🍎 목차 

    1. 브라우저의 렌더링 과정
    2. DOM API 란?
    3. 그래서 DOM 이 무엇인가?
    4. Virtual DOM(가상 돔)은 무엇일까?

     

    React로 프로젝트를 하면서 메모이제이션 기법을 사용하여 렌더링 성능을 개선하게 되었다.
    하지만 렌더링이라는 게 화면에 그려준다는 다소 추상적인 개념으로만 알고 있을 뿐, 정작 정확히 렌더링이 무엇인지에 대한 이해가 부족하다고 생각되어 공부하고 글로 정리하게 되었다. 

     

    1.  브라우저의 렌더링 과정

    주소창에 url을 입력하게 되면 브라우저는 HTML, CSS, JavaScript 등 렌더링에 필요한 리소스들을 서버에 요청하게 됩니다. 

    서버에서 받은 리소스들은 브라우저의 렌더링 엔진이 파싱(해석, 구문 분석, syntax analysis)해서 렌더링 하게 됩니다. 

     

    렌더링 : HTML, CSS, JavaScript로 작성된 문서를 파싱 하여 브라우저에 시각적으로 출력하는 것을 말한다.  

     

    HTML이 파싱을 거치면 -> DOM tree

    CSS가 파싱을 거치면 -> CSSOM tree

    JavaScreipt가 파싱을 거치면 -> AST(Abstract Syntax Tree)가 됩니다. 

     

    DOM : HTML이 파싱을 거친 tree 자료구조

     

     

    DOM과 CSSOM은 결합하여 렌더 트리(render tree)를 형성하게 됩니다. 

    렌더 트리(render tree)는 말 그대로 렌더링을 위한 트리 구조이기 때문에 브라우저 화면에 렌더링 되는 노드만으로 구성됩니다. 

    브라우저 화면에 렌더링 되지 않는 노드(ex. meta 태그, script 태그 등)와 CSS에 의해 비표시(ex. display: none)되는 노드들은 포함되지 않습니다. 

     

    2.  DOM API 란?

    JavaScript 코드에서 DOM API를 사용해 DOM이나 CSSOM을 변경할 수 있습니다.  DOM API라는 단어가 다소 생소하게 느껴질 수 있는데 보시면 이미 자주 사용했던 코드였던 것을 알 수 있습니다. 

     

    document.getElementById('apple') (DOM 탐색)의 경우 id가 'apple'인 HTML 요소를 가지고 온다는 의미를 담고 있는데 이 또한 DOM API입니다. 이 외에도 querySelector(DOM 탐색), createElement(DOM 조작), appendChild(DOM 조작)  모두 DOM API로 각각 DOM을 탐색하고 조작할 수 있습니다. 

     

    이렇게 DOM API를 통해 DOM이나 CSSOM을 변경하면 DOM과 CSSOM은 다시 결합하여 렌더트리를 형성하고(리플로우, 리페인트 과정을 거치게 됨) 렌더트리를 기반으로 브라우저에 다시 렌더링 됩니다. 

     

    즉, DOM API는 HTML의 요소들을 JS에서 제어하기 위한 명령들의 집합이라고 할 수 있어요. 

     

    - 리플로우 : 레이아웃 계산을 다시 하는 것을 말한다. 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다. 

    - 리페인트 : 재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것을 말한다. 

    - 레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 실행된다. 

     

     

    3.  그래서 DOM 이 무엇인가?

    지금 까지 얘기를 종합하자면 DOM은 HTML문서를 브라우저가 이해할 수 있도록 만든 Tree 자료구조로 HTML 문서의 계층적 구조와 정보를 표현합니다. 

    뿐만 아니라 DOM API를 통해 DOM을 제어할 수 있습니다. 

     

     

    4. Virtual DOM(가상 돔)은 무엇일까?

    글의 앞머리에서 언급했다시피 저는 React에서의 메모이제이션에 대해 공부 중 '메모제이션 기법은 값이 그대로인 요소들을 가상 돔에 새로 그리는 노동을 줄임으로써 성능을 아낄 수 있습니다.'라는 문장에서의 가상 DOM이라는 단어를 보고 이 글을 쓰게 되었는데요. 

     

    그래서 가상 돔(Virtual DOM)은 DOM과 어떤 차이가 있고 어떤 역할을 하는 걸까요?

     

    돔(DOM) vs 가상 돔(Virtual DOM)

    Virtual DOM은 실제 DOM과 같은 내용을 담고 있는 복사본이라고 생각하시면 쉽습니다.

    복사본은 실제 DOM이 아닌 JS 객체 형태메모리 안에 저장됩니다. 

     

    Virtual DOM은 실제 DOM의 복사본이기 때문에, 실제 DOM의 모든 element과 속성을 공유합니다.

     

    차이점은 브라우저에 있는 문서에 직접적으로 접근할 수 없다는 점입니다. 때문에 화면에 보이는 내용을 가상 돔을 통해 직접 수정할 수 없습니다. 

     

    가상 돔(Virtual DOM)은 왜 생겨났고, 어떻게 동작할까요?

    결론부터 말하자면, React나 Vue와 같은 라이브러리 및 프레임워크에서 가상 DOM을 사용하여 UI를 관리하고 효율적으로 업데이트하여 시간을 획기적으로 줄여줍니다. 

     

    가상 돔이 생겨난 배경

    예를 들어 #title의 색깔을 red로 바꾸고 싶다면, document.querySelector(‘#title”). style.color = “red”; 와 같은 DOM API가 사용됩니다. 

     

    브라우저는 HTML을 탐색해 해당 Element를 찾고, 해당 Element와 자식 Element들을 DOM에서 제거합니다. 이후 새롭게 수정된 Element로 이를 교체합니다. CSS는 이 과정 이후 다시 계산하여 결과적으로는 레이아웃 정보를 알맞게 수정됩니다. 새롭게 계산된 내용이 브라우저에 그려지는 방식으로 플로우가 진행됩니다. 

     

    사실 DOM조작은 빠른 알고리즘을 사용한다는 조건 하에선 그렇게 퍼포먼스적으로 무리가 있는 작업은 아니라고 합니다.(변경된 노드의 자식 노드들만 다시 그려지므로 ) 하지만 이를 반복적으로 수행한다면 무거운 작업이 될 수 있습니다. 

     

    그래서 가상 돔이 등장하게 되었습니다!

     

    가상 돔은 돔과 달리 실제 브라우저에 접근하는 것이 아닌 메모리에 접근하는 것이기에 가볍고 빠른 작업을 수행할 수 있게 됩니다. 

     

    구체적으로 가상 돔은 어떻게 동작할까? (React)

     

    리액트는 항상 두 개의 가상 돔 객체를 가지고 있습니다. 

     

    하나는 state 변경 전 즉 렌더링 이전의 화면 구조를 나타내는 가상돔,

    나머지는 렌더링 이후에 보이게 될 (업데이트된 부분이 적용된) 화면 구조를 나타내는 가상 돔입니다. 

     

    리액트는 state가 변경될 때마다, 실제 브라우저가 그려지기 이전에 1) 새로운 내용이 적용된 가상 돔을 생성하게 됩니다. 

     

    2) 렌더링 이전 두 개의 가상 돔을 비교해서 달라진 Element를 찾아서(Render Phase, Diffing) 3) 차이가 발생한 부분만 (브라우저상의) 실제 DOM에 적용(Commit Phase)하게 됩니다. (= Reconciliation = 재조정)

     

     

    만약 리스트 안에 10개의 항목이 바뀌었다면, 실제 DOM을 10번 수정하는 것이 아닌 Diffing 과정을 통해 달라진 요소들을 찾고, 집단화시켜 한번에 받아와 한꺼번에 실제 DOM에 적용하게 됩니다. 

     

    정리

    DOM과 비교했을 때 Virtual DOM은 실제 DOM의 가벼운 복사본으로서, 메모리 상에서 처리가 가능하다. 즉  DOM에 변경 사항이 생길 때마다 이전 버전의 Virtual DOM과 업데이트된 Virtual DOM을 비교하여 변경된 부분만 모아 한꺼번에 실제 DOM에 업데이트하는 방식으로 작동하기 때문에 웹 페이지 렌더링 성능 개선에 도움이 된다. 

     

    반응형

    댓글

Designed by Tistory.