브라우저 렌더링은 클라이언트의 요청에 의한 서버의 응답에서부터 시작된다. 예를 들어 우리가 브라우저의 주소창에 https://www.mydomain.com 이라는 URL을 입력한다고 하자. 그러면 URL의 호스트네임이 DNS를 통해 IP주소로 변환된고, 이 IP 주소를 갖는 서버에게 요청을 보낸다. 이때 이러한 루트 요청에 대해 서버는 암묵적으로 index.html을 응답한다. 즉, https://www.mydomain.com은 https://www.mydomain.com/index.html과 같다.
DOM 생성
1. 바이트 코드 -> 문자열
이 요청에 대해 서버는 index.html을 응답한다. 브라우저가 처음 받은 index.html은 바이트(2진수) 형태이다. 이 바이트 형식의 html 문서를 meta 태그의 charset 어트리뷰트에 선언된 인코딩 방식을 기준으로 문자열로 변환한다. 참고로 인코딩 방식이 meta 태그에 담겨있기도 하지만, 응답 헤더에도 포함되어있다. 브라우저는 이 헤더를 확인하고 문자열로 변환한다.
2. 문자열 -> 토큰
문자열로 변환된 index.html을 읽어서 문법적 의미를 갖는 최소 단위인 토큰으로 분해한다.
3. 토큰 -> 노드
각 토큰들을 객체로 변환하여 하나의 노드를 만든다. 이때 노드의 종류로는 문서노드, 요소노드, 어트리뷰트노드, 텍스트노드가 있다.
4. 노드 + 노드 + 노드 -> 렌더 트리
요소 간의 부자관계를 반영하여 모든 노드들을 트리 자료구조로 구성한다. 이때 만들어진 트리 자료구조가 DOM이다.
CSSOM 생성
렌더링 엔진은 index.html을 읽으면 DOM을 만들다가, link태그 or style태그를 만나면 DOM 생성을 중단하고 CSSOM을 생성하기 시작한다.
DOM 생성 방식과 동일하게 파싱과정(바이트 → 문자 → 토큰 → 노드 → CSSOM)을 거쳐 CSSOM을 만든다. 이후 html의 중단된 지점으로 돌아가 이어서 DOM을 생성을 한다.
렌더 트리 생성
생성된 DOM과 CSSOM은 렌더링을 위해 렌더 트리로 결합된다. 렌더 트리는 렌더링을 위한 트리 구조의 자료구조이다. 따라서 브라우저에 렌더링되는 노드들을(meta 태그, script 태그, display:none 제외) 가지고만 렌더 트리를 만든다.
레이아웃
완성되 렌더트리를 가지고 각 html 요소의 레이아웃(위치, 크기)을 계산한다.
페인트
렌더트리를 실제 브라우저에 그린다.
자바스크립트 파싱과 실행
DOM은 html 문서의 구조 뿐만 아니라 DOM API도 제공한다. 따라서 우리는 자바스크립트 코드에서 DOM API를 사용해서 DOM을 동적으로 조작할 수 있다.
렌더링 엔진이 html 문서를 파싱하다 script태그를 만나면 자바스크립트 코드를 파싱하기위해 제어권을 자바스크립트엔진에게 넘긴다. 따라서 지금부터는 자바스크립트 엔진이 하는 일들이다.
1. 토크나이징
단순한 문자열의 자바스크립트 소스코드를 토크나이징하여 문법적의미를 갖는 최소 단위인 토큰으로 분해한다.
2. 파싱
토큰들의 집합을 분석하여 AST(추상적 구문 트리)를 생성한다. AST는 토큰에 문법적 의미와 구조를 반영한 트리 구조의 자료구조이다.
3. 바이트코드 생성과 실행
AST를 인터프리터가 실행할 수 있도록 바이트 코드로 변환하고 인터프리터는 바이트 코드를 실행한다.
이렇게 자바스크립트 코드의 실행이 끝나면 자바스크립트 엔진은 제어권을 렌더링 엔진에게 돌려주며, 렌더링 엔진은 html 문서의 파싱을 중단한 지점으로 돌아가 DOM을 이어서 생성한다.
🧐 DNS란?
DNS란 간단히 말하면 IP주소와 도메인 주소를 이어주는 시스템이다.
출처
모던 자바스크립트 Deep Dive 38장. 브라우저의 렌더링 과정
'Development' 카테고리의 다른 글
Babel과 Babel polyfill (0) | 2021.09.25 |
---|---|
React 앱을 S3+CloudFront로 배포하기(3) - 도메인 연결 (0) | 2021.09.22 |
GIF파일 최적화 (0) | 2021.08.30 |
Gzip 적용하기 (Cloudfront) (0) | 2021.08.30 |
이미지 최적화 (0) | 2021.08.30 |