렌더링 원리/브라우저 렌더링

렌더링 시리즈 1 - 브라우저의 렌더링 원리

JakeTheMaverick 2023. 11. 13. 22:49



Intro

 모던 웹 프론트엔드 개발의 복잡성은 날이 갈수록 증가하고 있습니다.

 다양한 패키지 의존성 없이 개발하는 것이 어려워진 만큼 그 복잡도를 제어하기 위해서는

메인  라이브러리&프레임워크인 React, Nextjs 의 동작 원리를 더욱 깊게 이해하는 것이 중요하다고 생각합니다.

 

따라서 렌더링 시리즈를 시작하게 되었는데, 이 시리즈에서는 다음의 세 가지 주제를 순차적으로 다룹니다.

 

1. 브라우저의 렌더링 원리

 

2. 리액트의 렌더링

 

3. SPA와 서버 사이드 렌더링의 비교

 

세 주제를 순차적으로 정리하며 React, Nextjs의 단순한 사용법을 넘어

그 동작 원리를 면밀히 이해함으로써 

 예측 가능한 웹 프론트엔드 개발 지식을 확보할 수 있다고 생각합니다.



Critical Rendering Path  : 브라우저의 렌더링 단계

브라우저가 컨텐츠를 렌더링 하기 위해 아래의 단계들을 거쳐야 합니다.

 

 Document Object Model(DOM)

CSS Object Model(CSSOM)

 Render Tree

Layout

Paint

 

Critical Rendering Path

 

 

 * Deep dive 

  1. 브라우저가 사용자가 요청한 주소를 방문해 HTML,CSS을 다운로드한다.
  2. 브라우저는 HTML, CSS를 파싱해, 브라우저가 이해할 수 있는 형태의 객체 트리 모델인 DOM과 CSSOM 을 병렬적으로 생성한다.
  3. 이후 브라우저는 사용자 눈에 보이는 DOM 노드만을 순회한다, ( display:none과 같이 사용자 화면에 보이지 않는 요소는 방문하지않음.)
  4. 이 눈에 보이는 노드만을 대상으로 CSSOM 정보를 찾고, 여기서 발견한 CSS 스타일 정보를 이 노드에 적용한다( DOM노드에 CSS를 적용하는 과정은 크게 아래의 두 과정을 통해 이뤄집니다.)
  5. 3~4 과정에서 DOM트리와 CSSOM트리를 결합한 Render Tree를 생성합니다.
  6.  Layout
  7.  Paint
  • Layout:  Render Tree를 바탕으로 각 요소가 브라우저의 어느 좌표에 어느 크기로 나타나야 할지 정하는 작업
  • Paint:  Layout 과정을 바탕으로 실제 요소를 브라우저에 그리는 작업
    • Layouy, Paint 단계는 브라우저 렌더링 과정 중 리소스가 많이 소모되는 작업으로 이를 다시 계산하는 과정을 특별히 Reflow, Repaint라고 칭함, 이것을 줄이는 것이 브라우저 렌더링 최적화의 핵심.

 

 

Render Tree Construction

 

* Reflow , Repaint  란? 


1. Reflow(Layout): 이 과정은 페이지의 레이아웃을 계산하는 단계입니다. HTML 요소의 크기와 위치를 결정하는 작업이 이루어집니다. CSS 변경, DOM 추가/삭제, 페이지 초기 로딩 등으로 인해 발생하며, 전체 페이지에 영향을 미칠 수 있습니다. 빈번한 reflow는 페이지 성능에 부정적인 영향을 미칠 수 있습니다.


2. Repaint(Paint): 이 과정은 계산된 레이아웃을 기반으로 화면에 요소를 그리는 단계입니다. 색상, 배경 이미지 등 시각적 스타일 변경이 발생하면 repaint가 일어납니다. repaint는 reflow보다 덜 비용이 들지만, 여전히 빈번하게 발생하면 성능에 영향을 미칠 수 있습니다.

 

 

 

지금까지 브라우저가 크리티컬 렌더링 패스를 통해 HTML,CSS를 파싱하는 과정에 대해 알아봤습니다.

 

그렇다면, 렌더링 패스에서 Javascript는 도대체 어느 시점에 어떻게 처리되는 것일까요? 

JS는 언제, 어떻게 실행될까?

script load & execution


브라우저는 HTML 문서를 파싱하며 만나게 되는 <script> 태그를  default , async , defer  세 가지 방식으로 처리합니다.

 

1. default(기본 동작) :  script 태그를 만나면 해당 위치에서 HTML 파싱을 Block(차단)하고 , script를 로드한 뒤 실행함.

 

2. async(<script async>) : 스크립트 로드가 HTML 파싱과 병렬적으로 진행, 로드 즉시 script 를 실행

 

3. defer(<script defer>) :  스크립트 로드가 HTML 파싱과 병렬적으로 진행, HTML 파싱 완료 후 script 실행



하지만 이것은 어디까지나 브라우저의 기본 동작을 설명하기 위함입니다. 

 

실제 React를 사용해 개발하는  Single Page Application에서는 HTML, CSS, JS가 모두 로드된 이후  브라우저가 초기 형태의 HTML 페이지를 렌더한 뒤 , Javscript가 직접  DOM을 수정, 조작하는 형태로 UI가 업데이트 되는데요

(이러한 방식을 Client Side Rendering 이라고 합니다) 

 

이에 대한 내용은 다음 포스트인 리액트의 렌더링에서 더욱 자세히 알아보기로 합시다. 

 

 

 

 

Reference