브라우저 렌더링 전체 흐름에 대한 설명은 브라우저의 렌더링을 참고해주세요.
웹 브라우저가 HTML, CSS, JavaScript를 받아서 화면에 렌더링하고 실행하는 과정은 복잡한 단계로 이루어집니다. 이 포스트에서는 DOM(Document Object Model), CSSOM(CSS Object Model), AST(Abstract Syntax Tree) 생성 과정을 하나씩 뜯어보고, 내부 동작을 자세히 알아보겠습니다.
HTML 파일이 브라우저에 도착하면 렌더링 엔진이 이를 파싱해 DOM 트리를 생성합니다.
DOM 생성 과정
| 1. 바이트 스트림 -> 문자 스트림
<meta charset="UTF-8"> 같은 인코딩 정보를 읽고, 바이트를 문자 스트림(Character Stream)으로 변환합니다(예: UTF-8 → 유니코드 문자).| 2. 토큰화(Tokenization)
<div class="box">Hello</div>
<div → 시작 태그 시작
class="box" → 속성
> → 시작 태그 끝
Hello → 텍스트 노드
</div> → 종료 태그
| 3. 파싱과 DOM 트리 구축
(<div>)를 만나면 스택에 쌓고, 종료 태그(</div>)를 만나면 스택에서 꺼내 부모-자식 관계를 완성.<html>
<body>
<div>Hello</div>
</body>
</html>
Document
└── html
├── head
└── body
└── div
└── Text: "Hello"
| 4. 비동기 및 블록킹 요소
<script src="...">를 만나면 HTML 파싱이 중단(블록킹)되고, JS 파일을 다운로드 후 실행.<script async>: 다운로드와 파싱을 병렬로 진행, 다운 완료 시 실행.<script defer>: DOM 완성 후 실행.<link rel="stylesheet">: CSS 파일을 처리하며 렌더링이 지연됨.HTML에서 <link>나 <style> 태그를 만나면 CSS를 파싱해 CSSOM을 만듭니다.
과정
| 1. 바이트 스트림 -> 문자 스트림
| 2. 토큰화
div { color: red; font-size: 16px; }
div → 선택자
{ → 규칙 시작
color: red → 선언
; → 선언 구분
font-size: 16px → 선언
} → 규칙 끝| 3. 파싱과 CSSOM 트리 구축
body {
margin: 0;
}
div {
color: red;
}
CSSStyleSheet
├── Rule: "body { margin: 0; }"
└── Rule: "div { color: red; }"
| 4. 렌더링 블록킹
<script> 태그를 만나면 JavaScript 엔진(예: V8)이 코드를 처리합니다.
| 1. 바이트 스트림 -> 문자 스트림
| 2. 토큰화
function add(a, b) {
return a + b;
}
/*
function → 키워드
add → 식별자
( → 구분자
a → 식별자
, → 구분자
b → 식별자
) → 구분자
{ → 블록 시작
return → 키워드
a → 식별자
+ → 연산자
b → 식별자
; → 구분자
} → 블록 끝
*/
| 3. 구문 분석과 AST 생성
var x = 10;
AST (간소화)
VariableDeclaration
└── VariableDeclarator
├── Identifier: "x"
└── Literal: 10
| 4. 프리컴파일과 호이스팅
var x: 선언만 호이스팅, undefined로 초기화.function add() {}: 선언과 정의 모두 호이스팅.let, const: 호이스팅되지만 TDZ(Temporal Dead Zone)로 관리.| 5. 코드 생성과 실행