브라우저는 HTML, CSS를 해석 합니다.
그리고 HTML 문서의 해석이 끝나면 DOM 트리를 만들고,
CSS 문서의 해석이 끝나면 스타일 규칙을 만듭니다.
Render Tree 생성.
DOM Tree와 CSSOM Tree를 이용해 Render Tree를 생성합니다.
순수한 요소들의 구조와 텍스트만 존재하는 DOM Tree와는 달리
Render Tree에는 스타일 정보가 설정되어 있으며 실제 화면에 표현되는 노드들로만 구성됩니다.
⚠️
실제 화면에 표현되는 노드?
display: none 속성이 설정된 노드는 화면에 어떠한 공간도 차지하지 않기 때문에
Render Tree를 만드는 과정에서 제외됩니다.
추가로 visibility: invisible 은 display: none과 비슷하게 동작하지만, 공간은 차지하고 요소가 보이지 않게만 하기 때문에 Render Tree에 포함됩니다.
Layout.
브라우저의 뷰포트(Viewport) 내에서 각 노드들의 정확한 위치와 크기를 계산합니다.
다시 말해, 생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느위치에 어느크기로 출력될지 계산하는 단계입니다.
Paint
Layout 계산이 완료되면 요소들을 실제 화면을 그리게 됩니다.
이 때 처리해야 하는 스타일이 복잡할수록 Paint 단계에 소요되는 시간이 늘어나게 됩니다.
간단한 예시로 단색 background-color의 경우 paint 속도가 빠르지만,
그라데이션이나 그림자 효과 등은 painting 시간이 더 오래 소요됩니다.
🤔 Reflow
위에서 언급된 렌더링 과정을 거친 뒤에 최종적으로 페이지가 그려진다고 해서 렌더링 과정이 다 끝난것이 아닙니다.
어떠한 액션이나 이벤트에 따라 레이아웃(html 요소의 크기, 위치 등)을 수정하면 부모 노드들을 포함하여 그에 영향을 받는 자식 노드가 Layout 과정을 다시 수행하게 됩니다.
결국 Render Tree와 각 요소들의 크기와 위치를 다시 계산하게 됩니다. 이러한 과정을 Reflow라고 합니다.
Reflow가 발생하는 경우
페이지 초기 렌더링 (최초 Layout 과정)
윈도우 리사이징 (Viewport 크기 변경시)
DOM 노드의 추가, 제거
DOM 노드의 위치, 크기 변경 (margin, padding, border, width, height 등..)
이미지 크기 변경
폰트 변경, 텍스트 내용 변경
CSS3 애니메이션과 트랜지션
offset, scrollTop, scrollLeft과 같은 계산된 스타일 정보 요청
→ 화면의 구조가 변경되었다면 Reflow가 발생!
🖌️ Repaint
Reflow만 수행되면 실제 화면에 반영되지 않습니다. Render Tree를 다시 화면에 그려주는 과정이 필요합니다.
결국은 Paint 단계가 다시 수행되는 것이며 이를 Repaint 라고 합니다.
⚠️
무조건 Reflow 후 Repaint는 아님!
background-color, visibility와 같이 레이아웃에는 영향을 주지 않는 스타일 속성이 변경되었을 때는
Reflow를 수행할 필요가 없기 때문에 Repaint만 수행하게 됩니다.
✨ Reflow 최적화
cssText로 스타일을 한 번에!
// bad
const body = document.body;
body.style.width = '50px';
body.style.height = '100px';
// good
const body = document.body;
body.style.cssText = 'width: 50px; heigh: 100px;';