IT의 IT 블로그

브라우저 렌더링 과정과 엔진 구조 정리 본문

Frontend Basic (기초 이론)

브라우저 렌더링 과정과 엔진 구조 정리

IT의 IT 블로그 2026. 1. 6. 14:32

안녕하세요, 브라우저 렌더링 과정에 대해서 깊이 이해해보고자 블로그 포스팅을 하게 되었습니다.

대부분의 내용은 우아한 테크 기술 블로그와 네이버 D2 기술 블로그를 참고하고 정리하며 적게 되었습니다.

1. 이 글에서 설명하는 브라우저

  • Microsoft Edge
  • Samsung Internet
  • Firefox
  • Chrome
  • Opera

위 브라우저 중 Chromium 기반(Chrome, Edge 등)이 절대적인 비중을 차지하고 있으므로,

Blink 렌더링 엔진과 V8 JavaScript 엔진을 중심으로 설명합니다.

2025년 6월 기준

 

2. 웹 브라우저(web browser)란?

웹 브라우저는 웹 상의 자원을 요청하고, HTML 문서·이미지·CSS·JavaScript 등 다양한 콘텐츠를 해석하여 사용자에게 표시하는 소프트웨어입니다.
대표적인 브라우저로는 Chrome, Safari, Edge, Firefox 등이 있습니다.

브라우저의 주요 기능은 다음과 같습니다.

  • 사용자가 선택한 자원을 서버에 요청
  • 서버로부터 전달받은 응답을 해석
  • 웹 표준(HTML, CSS, JavaScript)에 따라 화면에 표시

HTML과 CSS의 명세는 W3C(World Wide Web Consortium) 에서 정의하며, 브라우저는 이를 기준으로 문서를 해석합니다.


3. 브라우저의 기본 구조

 

브라우저는 다음과 같은 주요 구성 요소로 이루어져 있습니다.

  1. 사용자 인터페이스(User Interface)
    - 주소창, 뒤로/앞으로 가기, 새로고침 버튼 등 브라우저의 GUI
  2. 브라우저 엔진(Browser Engine)
    - 사용자 인터페이스와 렌더링 엔진 사이의 동작을 조율
  3. 렌더링 엔진(Rendering Engine)
    - HTML, CSS를 파싱하여 화면에 표시
  4. 통신(Networking)
    - HTTP/HTTPS 요청과 응답 처리
  5. JavaScript 엔진(JS Engine)
    - JavaScript 코드를 파싱하고 실행
  6. UI 백엔드(UI Backend)
    - 콤보 박스와 창 같은 기본적인 장치를 그림.
      플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용.
  7. 데이터 저장소(Data Storage)
    - 쿠키, LocalStorage, IndexedDB 등 로컬 데이터 저장 영역

 

4. 렌더링 엔진

렌더링 엔진은 서버로부터 전달받은 문서를 파싱하여 화면의 픽셀로 변환하는 역할을 담당합니다.
HTML, CSS를 해석하여 DOM과 CSSOM을 생성하고, 이를 기반으로 레이아웃과 페인팅을 수행합니다.

4.1 렌더링 엔진들

브라우저마다 사용하는 렌더링 엔진이 다르며, 이로 인해 크로스 브라우징 이슈가 발생할 수 있습니다.

 

브라우저 렌더링 엔진
Edge EdgeHTML, Blink
Chrome Webkit, Blink(버전 28 이후)
Safari Webkit
FireFox Gecko

 

Chrome(정확히는 Chromium)은 WebKit을 포크하여 Blink 엔진을 개발해 사용하고 있습니다.

 

5. Chromium(크로미움) 이란?

Chromium은 오픈 소스 웹 브라우저 프로젝트로,
Blink 렌더링 엔진V8 JavaScript 엔진을 사용합니다.

Chrome은 Chromium을 기반으로 개발된 브라우저이며,
현재 Edge 역시 Chromium 기반으로 전환되었습니다.

6. 렌더링 엔진 동작 과정 요약

렌더링 엔진의 전체 흐름은 다음과 같습니다.

  1. HTML 파싱 → DOM 트리 생성
  2. CSS 파싱 → CSSOM 트리 생성
  3. DOM + CSSOM → Render Tree 생성
  4. Layout: 각 노드의 위치와 크기 계산
  5. Paint: 실제 픽셀로 그리기
  6. Composite: 레이어를 GPU에서 합성

※ 문서 수신은 Networking 계층에서 이루어지며, 렌더링 엔진은 전달받은 문서를 파싱하는 것부터 시작합니다.

 

 

7. 렌더링 엔진 상세 동작

웹킷 렌더링 엔진 동작 과정

7.1 WebKit 과 Blink 렌더링 흐름

  1. HTML을 파싱하여 DOM 노드를 생성하고, 이 DOM 노드들을 병합하여 DOM 트리를 생성
  2. CSS를 파싱하여, 스타일 규칙을 생성
  3. DOM 트리와 스타일 규칙을 사용하여, Attachment라는 과정을 통해 Render 트리를 생성
  4. Render 트리를 배치(Layout)
  5. Render 트리를 화면에 그림(Painting)

7.2 Gecko 렌더링 흐름

위의 그림은 Gecko의 렌더링 동작 과정입니다

 

Webkit과 Gecko는 용어가 약간 다르지만 렌더링 과정은 유사합니다.

Webkit Gecko 설명
Render Tree Frame Tree 렌더링 되는 노드 트리
Render Object Frame 렌더링 되는 노드
Layout Reflow 렌더링 되는 노드를 배치하는 과정
Attachment Frame Constructor 렌더링 되는 노드 트리를 만드는 과정
Content Sink DOM 노드를 만드는 과정

 

 

아래 그림은 브라우저 렌더링의 시간 흐름을 나타낸 것이 아니라,
Firefox와 Chrome이 내부 엔진을 어떤 방식으로 분리·구성하고 있는지를
비교한 아키텍처 다이어그램입니다.
같은 ‘브라우저 엔진’ 개념이라도 실제 구현에서는
Gecko처럼 통합형 구조와 Blink+V8처럼 분리형 구조로 나뉩니다.

 

8. Parser

Parser는 서버로부터 전송받은 문서의 문자열을 브라우저가 이해할 수 있는 구조로 변환하는 과정이며, Parser 결과는 문서 구조를 나타내는 노드 트리인데, 파싱 트리(parse tree) 또는 문법 트리(syntax tree)라고 지칭합니다.

9. DOM(Document Object Model)

아래 그림은 동작 과정 상세에서 DOM을 파싱 하는 과정이다.

9.1 Dom Parsing

  • 변환(Conversion): HTML의 원시 바이트(raw bytes)를 읽어와 해당 파일에 지정된 인코딩(UTF-8 등…)에 따라 문자열로 변환하는 과정
  • 토큰화(Tokenizing): 문자열을 W3C HTML5 표준에 따라 고유 토큰(<html>, <body>등, 꺽쇠괄호로 묶인 문자열)으로 변환합니다. 각 토큰은 특별한 의미와 고유한 규칙을 가짐
  • 렉싱(Lexing): 토큰을 해당 속성 및 규칙을 정의한 객체(Nodes)로 변환
  • DOM 생성(Dom construction): HTML은 상위-하위 관계로 정의할 수 있어, 트리 구조로 나타낼 수 있습니다.
    렉싱 과정을 거쳐 생성된 노드들을 트리 구조로 변환

4가지 과정을 모두 거치면 위의 그림과 같은 트리 형태의 DOM이 생성되며, 브라우저는 이후 모든 페이지 처리를 이 DOM을 사용한다.

10. CSSOM(CSS Object Model)

CSSOM MDN

CSS Object Model은 JavaScript에서 CSS를 조작할 수 있는 API 집합. HTML 대신 CSS가 대상인 DOM이라고 생각할 수 있으며, 사용자가 CSS 스타일을 동적으로 읽고 수정할 수 있는 방법입니다.

위의 그림과 같이 DOM을 생성하는 과정 그대로 CSSOM을 생성.

브라우저는 DOM을 생성하는 동안 외부 CSS를 참조하는 <link> 태그를 만나게 되면 브라우저에 리소스를 요청.

CSS의 원시 바이트(raw bytes)가 문자열로 변환된 후 차례로 토큰과 노드로 변환되고 마지막으로 CSSOM(CSS Object Model)이라는 트리 구조를 생성합니다.

10.1 CSSOM Tree

CSSOM이 트리 구조를 가지는 이유는 하향식으로 규칙을 적용하기 때문입니다.

최종 스타일을 계산할 때 브라우저는 해당 노드에 적용 가능한 가장 일반적인 규칙으로 시작해 더 구체적인 규칙을 적용하는 방식을 제공한다.

위의 CSSOM 트리 그림을 보면 하양식 규칙 적용에 대해 모습을 파악할 수 있습니다.

 

11. JS Load & CSS Load

HTML과 CSS, 자바스크립트를 파싱 하여 렌더 트리를 형성하고 화면에 그리는 과정을 최적화하면 브라우저의 렌더링 속도를 높여 사용성을 개선할 수 있습니다.

11.1 JavaScript Load

자바스크립트는 일반적인 <script> 태그는 HTML 파서를 차단하지만,
defer나 async 속성이 있는 경우에는 파싱 및 실행 시점이 달라집니다.

브라우저는 문서를 파싱 하다가 자바스크립트를 만나면 진행하던 파싱을 중지하고 자바스크립트 엔진에게 권한을 넘겨 자바스크립트를 파싱하고 실행합니다.

자바스크립트가 실행되는 동안 문서의 파싱은 중단됩니다.

자바스크립트는 파싱을 중단시키기 때문에, 보통 자바스크립트를 <head> 태그가 아닌 <body> 태그가 닫히기 바로 전에 사용되도록 하는 것이 좋습니다.

보통 bootstrap 같은 템플릿에 사용되는 JavaScript 들의 선언된 위치를 보면 <footer>쪽에 거의 모두 선언이 되어있는데 이런 이유가 크게 작용한다.

 

<script> 태그에 defer 속성을 주면, 문서 파싱은 중단되지 않고 문서 파싱이 완료된 이후에 자바스크립트가 실행됩니다.

HTML5에서 스크립트를 비동기(async)로 처리하는 속성이 추가되었으며, 자바스크립트가 별도의 맥락에 의해 파싱 되고 실행됩니다.

 

예)

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
document.getElementById('target').innerHTML = 'Hello JavaScript!';
</script>
</head>
<body>
<div id="target">This is a Heading</div>
</body>
</html>
 
// 오류 발생 // test.html:6 Uncaught TypeError: Cannot set property 'innerHTML'
of null // at test.html:6
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="target">This is a Heading</div>
<script>
document.getElementById('target').innerHTML = 'Hello JavaScript!';
</script>
</body>
</html>

11.2 CSS Load

CSS는 렌더링 차단 리소스(render blocking resource)입니다.

CSS는 렌더링을 할 때 반드시 필요한 리소스이기 때문에 브라우저는 빠르게 CSS를 다운로드하는 것이 좋습니다.

<head> 태그 안에서 정의하여 빠르게 리소스를 받을 수 있도록 하는게 성능상 좋습니다.

 

CSS는 DOM 구조를 변경하지는 않지만, 최종 렌더링과 일부 JavaScript 실행에 영향을 주기 때문에 렌더링 차단 리소스로 취급됩니다.

자바스크립트에서 스타일 정보를 요청하는 경우, CSS가 파싱 되지 않은 상태라면 스크립트 에러가 발생할 수 있습니다.

이런 문제를 해결하기 위해 Firefox 경우 로드 중이거나 파싱 중인 CSS가 있는 경우 모든 자바스크립트 실행을 중지합니다.

반면 Webkit의 경우 로드되지 않은 CSS 가운데 문제가 될 만한 속성이 있을 때에만 자바스크립트를 중단한다.

12. Attachment

CSSOM 트리와 DOM 트리를 결합하여, 표시해야 할 순서로 내용을 그려낼 수 있도록 하기 위해 렌더 트리를 형성하는 과정

(웹킷에서는 Attachment라고 지칭함)

렌더 트리는 화면에 표시되는 각 노드의 위치를 계산하는 레이아웃에 사용되고 픽셀을 화면에 그리는 페인트 과정에도 사용됩니다.

렌더 트리 구축

attachment 과정

  • 브라우저가 DOM 및 CSSOM을 렌더 트리에 결합
  • 렌더 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 CSSOM 스타일 정보를 결합

render tree 생성 과정

  • DOM 트리의 루트에서 시작하여 화면에 표시되는 노드 각각을 탐색
    • 화면에 표시되지 않는 일부 노드들 script, meta 태그 등..은 렌더 트리에 반영되지 않음
    • CSS에 의해 화면에서 숨겨지는 노드들은 렌더 트리에 반영되지 않음
  • 화면에 표시되는 각 노드에 대해 적절하게 일치하는 CSSOM 규칙을 찾아 적용
  • 화면에 표시되는 노드를 콘텐츠 및 계산된 스타일과 함께 렌더트리 생성

DOM 트리와 렌더 트리의 관계

렌더 트리는 DOM 트리 중 실제로 화면에 표시되는 요소들만을 대상으로 구성된 트리입니다.  

예) <head> 태그와 같은 비시각적 DOM 노드는 렌더 트리에 추가되지 않습니다.

tips)

  • CSS로 인해 display 속성에 none 값이 할당된 노드들을 렌더 트리에 추가되지 않음
  • visibility:hidden은 렌더 트리에 포함됨
    (visibility 속성에 hidden 값이 할당된 노드는 화면에 공간을 차지하기 때문에 렌더 트리에 포함)

13. Layout

렌더 트리가 생성되면 브라우저는 뷰포트(화면) 내에서 각 노드가 차지해야 할 정확한 위치와 크기를 계산합니다.  
이 과정을 Layout(또는 Reflow)라고 합니다.

Layout 과정에서는 박스 모델(Box Model)을 기준으로 요소의 너비, 높이, 여백, 테두리, 위치 등이 계산됩니다.  
또한 CSS에서 %나 em과 같은 상대 단위를 사용한 경우, 현재 뷰포트와 스타일 규칙을 기준으로 픽셀(px) 단위의 절대값으로 변환됩니다.

요소의 크기나 위치가 변경되거나 DOM이 추가·삭제되거나 브라우저 창의 크기가 변경되면 Layout이 다시 수행될 수 있습니다.  
일반적으로 이러한 Layout 재계산이 발생하는 상황을 Reflow라고 부릅니다.

Reflow가 발생하면 영향을 받는 노드들의 위치를 다시 계산해야 하며, 상황에 따라 이후 Paint 단계까지 다시 수행되기 때문에 성능 비용이 큽니다.

14. Painting

 

Paint는 Layout 결과를 바탕으로 각 요소의 텍스트, 색상, 배경, 테두리, 그림자, 이미지 등을 실제 픽셀로 그리는 과정입니다.  
렌더 트리에 포함된 시각적 요소들이 이 단계에서 화면에 표현됩니다.

즉, Layout 단계에서 요소를 어디에 얼마나 크게 배치할지 결정했다면,  
Paint 단계에서는 해당 요소를 어떤 색상과 스타일로 화면에 그릴지를 확정하고 픽셀 단위로 변환합니다.

15. UI가 업데이트되는 3가지 상황

  • 다시 Layout이 발생하는 경우
    : 주로 요소의 크기나 위치가 바뀔 때, 혹은 브라우저 창의 크기가 바뀌었을 때 다시 발생
  • Paint부터 다시 발생되는 경우
    : 주로 배경 이미지나 텍스트 색상, 그림자 등 레이아웃의 수치를 변화시키지 않는 스타일의 변경이 일어났을 때 발생.
  • 레이어(painting 할 영역을 나눠놓는것) 의 합성만 다시 발생하는 경우
    : Layout과 Paint을 수행하지 않고 레이어의 합성만 발생하기 때문에 성능상으로 가장 큰 이점을 가짐

 

15.1 Layout부터 다시 발생하는 경우 (Reflow)

  • 요소의 크기나 위치가 변경되는 경우  
  • DOM이 추가되거나 삭제되는 경우  
  • 브라우저 창 크기가 변경되는 경우

    이 경우 레이아웃 재계산이 필요하므로 비용이 가장 크며, 이후 Paint 단계까지 함께 발생할 수 있습니다.
      

    Reflow (다시 Layout)이 발생하는 경우

 15.2 Paint부터 다시 발생하는 경우 (Repaint)

  • 배경색, 텍스트 색상, 그림자 등  
  • 레이아웃에는 영향을 주지 않는 스타일 변경  

    Layout 과정은 생략되고 Paint 단계부터 다시 수행되므로 Reflow에 비해 성능상 이점이 있습니다.

    Repaint가 발생하는 경우

15.3 Composite(합성)만 다시 발생하는 경우

  • transform, opacity 등의 변경 

    Layout과 Paint를 다시 수행하지 않고 레이어를 GPU에서 합성(Composite)하는 단계만 발생하므로,  
    일반적으로 가장 성능상 유리한 업데이트 방식입니다.
    레이어의 합성만 다시 발생하는 경우

 

16. 요약

브라우저의 기본적인 렌더링 흐름은 다음과 같습니다.

1) HTML을 파싱하여 DOM 트리를 생성합니다. (DOM Parsing)  
2) CSS를 파싱하여 CSSOM 트리를 생성합니다. (CSS Parsing)  
3) DOM과 CSSOM을 결합하여 렌더 트리를 생성합니다. (Render Tree Construction)  
4) 렌더 트리를 기반으로 각 요소의 위치와 크기를 계산합니다. (Layout)  
5) 계산된 결과를 실제 픽셀로 화면에 그립니다. (Paint)  
6) 필요에 따라 레이어를 합성하여 최종 화면을 완성합니다. (Composite)

17. 브라우저 렌더링 순서 정리: google.com을 입력했을 때

브라우저에서 google.com을 입력했을 때의 동작은 크게 문서 구성 단계와 화면 출력 단계로 나누어 볼 수 있습니다.

17.1 Construction (문서 구성 단계)

1) 사용자가 URL을 입력합니다.  
2) 브라우저가 도메인을 기반으로 IP 주소를 조회(DNS)합니다.  
3) 브라우저가 서버에 HTTP/HTTPS 요청을 전송합니다.  
4) 서버가 HTML 등의 응답을 반환합니다.  
5) 브라우저는 HTML을 파싱하며 DOM 트리를 생성합니다.  
6) 파싱 중 <style> 태그나 외부 CSS(<link>)를 만나면 CSSOM을 생성합니다.  
7) 파싱 중 일반 <script> 태그를 만나면 파싱을 일시 중단하고 JavaScript를 파싱·실행합니다.  
8) DOM과 CSSOM이 준비되면 렌더 트리를 생성합니다.

17.2 Operation (화면 출력 단계)

1) 렌더 트리를 기반으로 요소의 위치와 크기를 계산합니다. (Layout)  
2) 계산된 결과를 픽셀로 화면에 그립니다. (Paint)  
3) 레이어를 합성하여 최종 프레임을 구성합니다. (Composite)  
4) 사용자에게 결과 화면이 표시됩니다.

18. 글을 마무리하며

프론트엔드 개발에서 성능 최적화는 브라우저의 렌더링 흐름, 특히 CRP(Critical Rendering Path)를 이해하고 이를 제어하는 과정과 밀접하게 연결되어 있습니다.  
어떤 리소스가 렌더링을 차단하는지, 어떤 변경이 Layout, Paint, Composite 중 어느 단계까지 영향을 미치는지를 이해하는 것이 중요합니다.

19. 번외: Virtual DOM

가상 DOM(Virtual DOM)은 실제 DOM을 직접 조작하는 대신, 메모리 상에서 UI 변경을 먼저 계산한 뒤 변경 사항을 한 번에 실제 DOM에 반영하는 전략입니다.  
변화가 많은 화면(View)에서 DOM 변경 비용을 줄이기 위해 사용되며, React는 이러한 접근 방식을 대표적으로 활용합니다.

React의 구체적인 렌더링 과정은 다음 글에서 별도로 정리할 예정입니다.

지금까지 읽어주셔서 감사합니다.