오늘은 브라우저 렌더링 과정을 알아보고, 그에 대한 최적화하는 방법을 알아보겠습니다.
지난 포스트를 작성하면서, script 옵션이나 위치에 따라 렌더링 순서나 최적화에 영향을 미치는 것을 알아보았습니다. 이 과정에서 브라우저에 화면이 어떤 순서를 통해 렌더링이 되는 지 알아보고 어느 부분을 신경써서 개선할 수 있는지 알아보기 위해 이번 포스트를 작성하였습니다. MDN 문서를 주로 참고하여 작성하였고 틀린 부분이나 잘못된 부분이 있으면 댓글로 알려주시면 감사하겠습니다.
네트워크로부터 데이터를 받아온 이후, 브라우저 렌더링 과정은 다음과 같이 이루어집니다.
- 구문 분석(parsing)
- 렌더(render)
- 상호작용(interactivity)
1. 구문 분석 (parsing)
브라우저가 네트워크를 통해 받은 데이터를 DOM이나 CSSOM으로 바꾸는 단계입니다.
DOM과 CSSOM은 렌더러가 화면에 페이지를 그리는데 사용됩니다.
- HTML을 DOM (Document Object Model) 트리로 변환
- CSS를 CSSOM (CSS Object Model) 트리로 변환
- 프리로드 스캐너가 우선순위가 높은 자원을 미리 요청
2. 렌더 (render)
렌더링 과정에는 스타일, 레이아웃, 페인트 그리고 합성이 포함됩니다. CSSOM과 DOM 트리는 구문 분석되는 과정에서 생성되고 렌더 트리로 합성됩니다.
- DOM, CSSOM을 결합하여 렌더 트리 생성
- 각 요소의 크기와 위치를 계산하고 뷰포트 크기를 고려하여 레이아웃 결정 (변경 사항이 있을 경우 리플로우 발생)
- 계산된 레이아웃을 실제 픽셀로 변환. 텍스트, 색상, 이미지 등 시작적 요소를 그림 (성능 향상을 위해 여러 레이어로 나눌 수 있음)
- 여러 레이어를 올바른 순서로 합쳐 최종화면 구성
* 리플로우(reflow)와 리페인트(repaint)
리플로우와 리페인트는 모두 브라우저의 렌더링 과정에서 중요한 부분을 차지하며, 웹 성능에 큰 영향을 미칩니다.
reflow: 레이아웃 계산을 다시 하는 과정으로 DOM 요소의 추가, 제거, 크기 변경 등으로 인해 발생
예) width, height, margin 변경 시 발생
repaint: 변경된 요소의 외관을 화면에 다시 그리는 과정으로 시각적 스타일 변경 시 발생하며, 레이아웃에는 영향을 주지 않음
예) color, background-color 변경 시 발
일반적으로 리플로우가 더 많은 비용이 들기 때문에, 가능한 리플로우를 최소화하는 것이 좋습니다.
3. 상호 작용 (interactivity)
메인 쓰레드가 페이지를 그리는 것을 완료하면, 모든 것이 준비되었다고 생각할 수 있지만 지연된 javascript를 다운했거나, onload 이벤트가 발생할 때 코드가 실행된다면 메인 쓰레드는 여전히 바쁠 것입니다.
- Time to Interactive (TTI): 페이지가 사용자와 상호작용할 준비가 되는 시점으로 첫 번째 콘텐츠가 포함된 페인트 이후 페이지가 사용자와의 상호 작용에 50m 이내로 응답할 때를 상호 작용 가능한 시점으로 봅니다.
성능 최적화
- 첫 14KB에 중요한 콘텐츠 포함
- 이미지 크기 미리 지정으로 리플로우 방지
- JavaScript 실행이 렌더링을 막지 않도록 주의 (async, defer 사용)
- 레이어 사용은 성능 향상에 도움되지만 과도한 사용 주의
참고자료
웹페이지를 표시한다는 것: 브라우저는 어떻게 동작하는가 - 웹 성능 | MDN
사용자는 로드가 빠르고 상호작용이 원활한 컨텐츠로 이루어진 웹 경험을 원합니다. 따라서 개발자는 이 두 가지 목표를 달성하기 위해서 부단히 노력해야합니다.
developer.mozilla.org
웹 성능 | MDN
웹 성능은 객관적인 측정치이면서 로드 시간과 런타임을 어떻게 인식하는지에 대한 주관적인 사용자 경험입니다. 사이트가 로드되는 데 걸리는 시간, 로드 후 상호작용에 반응할 수 있게 되기
developer.mozilla.org