- Published on
브라우저의 렌더링 과정
브라우저의 렌더링 과정
등장 배경 및 개요
- V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경인 Node.js의 등장으로 웹 브라우저를 벗어나 서버 사이드 애플리케이션 개발에서도 사용할 수 있는 범용 언어 개발이 되었음
- 대부분의 언어는 운영체제나 가상 머신 위에서 실행되면 웹 애플리케이션의 클라이언트 사이드 자바스크립트는 브라우저에서 HTML, CSS와 함께 실행됨
파싱(parsing)
과정
- 프로그래밍 언어의 문법에 맞게 작성된 텍스트 문서를 읽어 들여 실행하기 위해 텍스트 문서의 문자열을
토큰으로 분해하고, 토큰에 문법적 의미와 구조를 반영하여 트리 구조의 자료구조인파스 트리를 생성하는 일련의 과정
실행
- 파스트리를 기반으로 중간 언어인 바이트코드를 생성하고 실행함
렌더링(rendering)
- HTML, CSS, 자바스크립트로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것
렌더링 과정
브라우저는 HTML, CSS, 자바스크립트, 이미지, 폰트 파일 등렌더링에 필요한 리소스를 요청하고서버로부터 응답받음렌더링 엔진은 서버로부터 응답된 HTML과 CSS를파싱하여DOM과 CSSOM을 생성하고 이들을 결합하여렌더 트리를 생성- 브라우저의
자바스크릡트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여AST를 생성하고바이트코드로 변환하여실행
- DOM API를 통해 DOM이나 CSSOM을 변경할 수 있고 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합됨
- 렌더 트리를 기반으로 HTML 요소의
레이아웃을 계산하고 브라우저 화면에HTML 요소를 페인팅함
요청과 응답
브라우저의 핵심 기능
- 필요한
리소스를서버에 요청 - 서버로부터
응답 - 시각적으로
렌더링
- 필요한
Q. 개발자 도구의 Network 패널을 활성화 했을 때, 요청도 하지 않은 리소스가 응답된 이유?
- A. HTML을 파싱하는 도중에
외부 리소스를 로드하는 태그(link, img, script)를 만나면 파싱을 중단하고해당 리소스 파일을 서버로 요청하기 때문임(⭐)
- A. HTML을 파싱하는 도중에
HTTP 1.1과 HTTP 2.0
- HTTP는 웹에서 브라우저와 서버가 통신하기 위한 프로토콜 규약
HTTP 1.1
- 커넥션당
하나의 요청과 응답만 처리- 여러 개의 요청을 한 번에 전송 및 응답할 수 없음
- 리소스 요청은 개별적으로 전송되고 응답 또한
개별적으로 전송됨 - 동시 전송이 불가능한 구조
HTTP 2
- 커넥션당
여러 개의 요청과 응답이 가능- 동시 전송 가능
- HTTP/1.1에 비해 페이지 로드 속도가 50% 정도 빠름
HTML 파싱과 DOM 생성
순수한 텍스트인 HTML 문서를 브라우저에 시각적인 픽셀로 렌더링하려면
HTML 문서를 브라우저가 이해할 수 있는 자료구조로 변환하여 메모리에 저장해야 함<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="style.css"> </head> <body> <ul> <li id="apple">Apple</li> <li id="banana">Banana</li> <li id="orange">Orange</li> </ul> <script src="app.js"></script> </body> </html>- 응답받은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인 DOM을 생성
서버에 존재하던 HTML 파일이 브라우저 요청에 의해 응답
서버는 브라우저가 요청한HTML 파일을 읽어 들여메모리에 저장한 다음 메모리에 저장된바이트를 인터넷 경유하여응답
브라우저는 서버가 응답한 HTML 문서를 바이트 형태로 응답
바이트 형태의 문서는
meta태그의charset어트리뷰트에 의해 지정된인코딩방식(UTF-8)문자열로 변환
- 문자열로 변환된 HTML 문서를 읽어들여 문법적 의미를 갖는 코드의 최소 단위인
토큰들로 분해 - 토큰 → 객체로 변환하여
노드생성 - 중첩 관계를 갖는 HTML 요소의 부자 관계 형성(트리 자료구조화) - DOM 생성
CSS 파싱과 CSSOM 생성
- 렌더링 엔진은 HTML 을 처음부터 한 줄씩 순차적으로 파싱하여 DOM을 생성하다가
외부 리소스를 로드(link, style)하는 태그를 만나면 DOM 생성을 일시 중단- HTML와 동일한 파싱 과정을 거치며 해석하여
CSSOM을 생성
- HTML와 동일한 파싱 과정을 거치며 해석하여
- CSS 파싱 완료 후 HTML 파싱이 중단된 시점부터
DOM 생성 재개
body {
font-size: 18px;
}
ul {
list-style-type: none;
}
외부 리소스를 로드하는 태그(
link)를 만나서 위와 같은 style.css 파일이 서버로부터 응답이 되었다고 가정서버로부터 CSS 파일이 응답되면 렌더링 엔진은 HTML과 동일한 해석 과정을 거쳐 CSSOM을 생성함

렌더 트리 생성
DOM과CSSOM은 렌더링을 위해렌더 트리로 결합됨렌더 트리렌더링을 위한
트리 구조의 자료구조브라우저 화면에
렌더링되는 노드만으로 구성HTML 요소의
레이아웃을 계산하는 데 사용되며 브라우저 화면에 픽셀을 렌더링하는페인팅 처리에 입력됨
리렌더링발생되는 경우자바스크립트에 의한
노드 추가또는삭제브라우저 창의 리사이징에 의한
뷰포트 크기 변경HTML 요소의 레이아웃(위치, 크기)에 변경을 발생시키는width/height,margin,padding,border,display,position,top/right/bottom/left등의스타일 변경
레이아웃 계산과페인팅이 재차 발생하면성능에 악영향을 주는 작업이므로 피해야 함
자바스크립트 파싱과 실행
- HTML 문서를 파싱한 결과물로서 생성된
DOM은 HTML 문서의 구조와 정보뿐만 아니라 HTML 요소와 스타일 등을 변경할 수 있는프로그래밍 인터페이스로서DOM API를 제공함- DOM API를 통해 DOM을 동적으로 조작할 수 있음
- 자바스크립트
파싱과실행은 브라우저의 렌더링 엔진이 아닌자바스크립트 엔진이 처리함- 자바스크립트 엔진은 ECMAScript 사양을 준수
렌더링 엔진이 HTML과 CSS를파싱하여 DOM과 CSSOM을 생성하듯이자바스크립트 엔진은 자바스크립트를 해석하여AST(추상적 구문 트리)를 생성AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드인바이트코드를 생성하여 실행
토크나이징
- 자바스크립트 소스코드를 어휘 분석하여 문법적 의미를 갖는
코드의 최소 단위인토큰들로 분해
파싱
- 토큰들의 집합을
구문 분석하여AST(추상적 구문 트리)를 생성- AST를 사용하면
Typescript,Babel,Prettier같은트랜스파일러구현을 할 수 있음 - AST Explorer 웹사이트 - AST 생성
- AST를 사용하면
바이트코드 생성과 실행
AST는 인터프리터가 실행할 수 있는 중간 코드인바이트코드로 변환되고인터프리터에 의해 실행- V8 엔진의 경우 자주 사용되는 코드는
터보팬이라 불리는컴파일러에 의해 최적화된머신 코드로 컴파일되어 성능을 최적화
- V8 엔진의 경우 자주 사용되는 코드는
리플로우와 리페인트
DOM API가 사용되어, 변경된DOM과CSSOM은 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐브라우저의 화면에 다시 렌더링되는 흐름리플로우레이아웃 계산을 다시 하는 것
리페인트재결합된 렌더 트리를 기반으로 다시페인트하는 것
자바스크립트 파싱에 의한 HTML 파싱 중단

- 브라우저는 동기적으로, 위에서 아래 방향으로 순차적으로 HTML, CSS, 자바스크립트를 파싱하고 실행함
script 태그의 위치에 따라 HTML 파싱이 블로킹되어DOM 생성이 지연될 수 있음(⭐⭐)- HTML 파싱이 중단되는 위치(app.js)에서 DOM이나 CSSOM을 변경하는
DOM API을 사용할 경우 DOM이나 CSSOM이 이미 생성되어 있어야 함- DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작하면 에러가 발생할 수 있음
- 자바스크립트
로딩/파싱/실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 않아 페이지 로딩 시간이 단축됨
- HTML 파싱이 중단되는 위치(app.js)에서 DOM이나 CSSOM을 변경하는
script 태그의 async/defer 어트리뷰트
- 자바스크립트 파싱에 의한 DOM 생성 중단 문제를 근본적으로 해결하기 위해 HTML5부터 script 태그에
async와defer어트리뷰트가 추가됨- src 어트리뷰트가 없는 인라인 자바스크립트에서는 사용할 수 없음
<script async src="extern.js"></script>
<script defer src="extern.js"></script>
async 어트리뷰트

- HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기 적으로 동시에 진행됨
IE10 이상에서 지원
defer 어트리뷰트

- async 어트리뷰트와 마찬가지로 진행되지만
DOM 생성이 완료된 직후에 진행되므로 DOM 생성이 완료된 이후 실행되어야 할 자바스크립트에 유용함 IE10 이상에서 지원
Referenced
- 이응모, 『모던 자바스크립트 Deep Dive』, 위키북스(2022.4.25), 643 ~ 659p