#back_to_basic
다시 처음부터!라는 마음으로 공부해보자! 아자아자!
1. 브라우저의 작동방식
우리의 브라우저는 아래와 같은 순서로 동작한다.
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]
화이팅이다!
'Web' 카테고리의 다른 글
[BB] useRef가 사용되는 경우 (0) | 2023.12.08 |
---|---|
[BB] Javascript: 불변성(immutability) (0) | 2023.10.26 |
[BB] Javascript: 비동기 프로그래밍 (0) | 2023.10.25 |
[BB] JavaScript: var, let, const의 차이 (0) | 2023.10.25 |
[BB] Javascript: 실행 컨텍스트와 스코프 (0) | 2023.10.24 |