Web

[BB] 브라우저의 렌더링과 Virtual DOM

hololo 2023. 10. 25. 23:36

#back_to_basic
다시 처음부터!라는 마음으로 공부해보자! 아자아자!

1. 브라우저의 작동방식

우리의 브라우저는 아래와 같은 순서로 동작한다.

출처: https://velog.io/@gga01075/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EA%B3%BC%EC%A0%95

HTML을 파싱하여 DOM Tree를 만드는 데,
파싱을 하는 과정에서 임베디드된 이미지, 비디오, 스타일 시트가 있다면 이 자원들도 같이 로드하여 파싱한다.

스타일 시트를 파싱하면서 스타일 규칙을 만들어 attachment라는 과정을 거쳐 Render Tree를 만들어낸다.

*이 때 script를 만나면 파싱을 중단하게 되는데,
이때문에 제일 하단에 script를 선언해야한다는 이야기가 나온다.

 

❓DOM Tree와 Render Tree

둘은 같은 것이 아니다.

Render Tree는 문서의 시각적 측면에서 올바른 순서대로 내용을 그리도록 하기 위한 목적을 가지고 있다.
즉, 문서에 보이지 않아도 되는 display: none;을 가지는 노드나, 불필요한 head같은 것들은 제외한다.

 

이렇게 Render Tree를 만든 뒤에,
reflow(레이아웃, 레이아웃팅)를 하는데, 레이아웃에서는 render tree의 목적에 맞게 각 요소의 구체적인 위치와 크기를 연산한다.

결과적으로 이를 브라우저에 픽셀을 렌더링하는 페인팅 과정(painting)을 거치게 되는데,
이를 위해 각 노드를 거치면서 paint() 메소드를 호출한다.

이후엔, 합성(composite) 단계가 조건적으로 발생하는데,
이 단계에서는 생성된 Layer들을 합성하여 단 한장의 비트맵으로 만든다.

이 모든 과정을 '렌더링'한다고 말한다.

(파싱 => 돔, 렌더트리 생성 => 플로우(레이아웃) => 페인트 => 합성)

 

 

2. Reflow와 Repaint

브라우저에 변화가 일어나게 되면(브라우저 크기가 줄어든다든가, 사용자의 입력이 들어온다든가 등),
Reflow(layout)과 repaint가 발생하게 된다.

먼저, 레이아웃의 경우)
렌더트리를 구축 => 레이아웃 => 리페인트 => 레이어 업데이트 => 합성
을 하게 되고,

리페인트만 한다면)
렌더트리를 구축 => 리페인트 => 레이어 업데이트 => 합성
을 하게 된다.

레이아웃과 리페인트가 발생할 때는 UI의 화면 표현이 느려지기 때문에, 코드를 작성할 때는 이를 최소화해야한다.

특히, Reflow의 경우 부모/조상 요소까지 레이아웃 계산을 다시 하기때문에 repaint보다 더 심각한 성능 저하를 만들기도 하기때문에,
이를 유발하는 조정은 최적화가 필요하다.

 

❓ Reflow(Layout)을 발생시키는 요인

  • 윈도우 리사이징
  • 폰트의 변화
  • 스타일의 추가/제거
  • 내용 변화
  • 클래스 attribute의 동적 변화

등이 있다.
사실 너무 많아서 이를 다 피할 수는 없지만, 많은 글들이 이를 인지하고 최적화를 해야한다고 말한다.

❓최적화하는 방안들

  • 최대한 DOM 구조상 말단 노드에만 클래스를 사용(리플로우의 영향을 최소화)
  • 인라인 스타일 자제(리플로우 자제, 클래스를 사용할 것)
  • 애니메이션 position은 absoulute와 fixed로
  • CSS에서의 JS 표현식 자제

등이 있다고 한다.

 

 

3.  Virtual DOM

최근 웹 어플리케이션들의 규모가 커져가면서, 각 데이터를 표현하는 요소들이 많아지고
그에 따라 표현해야하는 노드들이 많아진다.

이 의미는 DOM이 커지고, 변화가 생긴다면 이 큰 DOM에 직접 접근하여 계속해서 리렌더링을 해주어야하기 때문에 성능에 무리가 간다.
(계속해서 리플로우 => 리페인트가 일어난다는 의미)

Virtual DOM은 실제 DOM의 가벼온 사본으로,
실제 DOM에 접근하여 조작하는 대신, 이를 추상화한 자바스크립트 객체를 구성하여 사용할 수 있게 한다.

DOM의 상태를 메모리에 저장하고,
변경 전과 변경 후의 상태를 비교한 뒤 최소한의 내용만 반영하는 기능이다.
이를 통해 성능을 향상시킨다.

가상 DOM은 DOM의 상태를 메모리 위에 계속 올려두고,
DOM에 변경이 있을 경우 해당 변경을 반영한다.

 

❓ 어떻게 가상돔을 사용하는가

1. 데이터가 업데이트되면, 전체 UI를 Virtual DOM에 리렌더링함
2. 이전 Virtual DOM에 있던 내용과 현재의 내용을 비교함
3. 바뀐 부분만 실제 DOM에 적용이 됨

이 과정에서는, 컴포넌트가 업데이트될 때, 레이아웃 계산(reflow)이 한번만 이뤄진다.

작은 규모의 레이아웃(reflow)이 여러번 발생하는 것보다,
큰 규모의 레이아웃이 한번 발생하는 것은 성능상의 큰 차이를 나타낸다.

 

 

[References]

Reflow, Repaint을 알아보자!

브라우저의 동작과정

[React] DOM이란? 가상돔이 나오게 된 이유

[React] 가상돔이란?

렌더링 6단계

 

 

화이팅이다!