JavaScript/모던 자바스크립트 Deep Dive
28. 브라우저 렌더링 과정
sandwe
2022. 9. 26. 23:33
요청과 응답
- 브라우저의 주소창에 http://poiemaweb.com을 입력하면 루트 요청이 poiemaweb.com 서버로 전송된다. 서버는 루트 요청에 대해 암묵적으로 index.html을 응답한다.
- 브라우저의 렌더링 엔진은 전달받은 index.html을 파싱하는 도중 외부 리소스를 로드하는 태그(link, img, script 등)를 만나면 HTML 문서의 파싱을 일시 중단하고 해당 리소스 파일을 서버에 요청한다.
HTML 파싱과 DOM 생성
- 서버로부터 응답된 HTML 문서는 문자열로 이루어진 순수 텍스트이다. 브라우저에 시각적인 픽셀로 렌더링하기 위해서 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조(객체)로 변환해 메모리에 저장한다.
- 이때, 브라우저가 이해할 수 있는 트리 형태의 자료구조를 DOM(Document Object Model)이라 한다.
- 파싱 과정: 바이트 -> 문자 -> 토큰 -> 노드 -> DOM
CSS 파싱과 CSSOM 생성
- 렌더링 엔진은 HTML 문서를 한줄씩 파싱해 DOM을 생성해가다가 link나 style 태그를 만나면 일시 중단하고 서버에 태그의 href 속성에 지정된 CSS 파일을 서버에 요청한다.
- 응답받은 CSS 파일을 파싱하여 CSSOM(CSS Object Model)을 생성한다. CSS 파일의 파싱이 끝나면 HTML 파싱이 중단된 시점부터 다시 HTML 파싱을 진행한다.
렌더 트리 생성
- 생성이 완료된 DOM와 CSSOM은 렌더링을 위해 렌더 트리(render tree)로 결합된다.
- 렌더 트리는 각 HTML 요소의 레이아웃을 계산하는 데 사용된다. 또한, 브라우저 화면에 픽셀을 렌더링하는 페인팅 처리에도 사용된다.
📓 리렌더링: 레이아웃 계산과 페인팅을 다시 실행하는 것
📓 리렌더링되는 경우
1️⃣ JavaScript를 통한 노드 추가/삭제
2️⃣ 브라우저 창 리사이징(resizing)으로 인한 뷰포트 크기 변경
3️⃣ HTML 요소의 레이아웃(크기, 위치)에 변경을 야기하는 width, height, margin, padding, border, position, display 등의 스타일 변경
❗️리렌더링이 빈번하면 성능에 좋지 않다. 리렌더링을 줄일 수 있는 방안을 생각해야 한다.
자바스크립트 파싱과 실행
- HTML 문서를 한줄씩 해석하다 script 태그를 만나면 일시 중단하고, script 태그의 src 속성에 정의된 자바스크립트 파일을 서버에 요청한다.
- 자바스크립트의 파싱과 실행은 자바스크립트 엔진이 따로 처리한다. 자바스크립트 엔진은 AST(Abstract Syntax Tree, 추상적 구문 트리)를 생성한다.
리플로우와 리페인트
- 자바스크립트의 DOM API를 사용하여 DOM이나 CSSOM을 변경하면 변경된 DOM과 CSSOM을 다시 렌더 트리로 결합하고, 리플로우, 리페인트 과정을 거쳐 다시 렌더링된다.
- 레이아웃이 변하지 않으면 리페인팅만 실행된다.
script 태그의 위치
- 브라우저는 위에서 아래 방향으로 순차적으로 파일을 해석하기에 동기적으로 수행된다.
- 만약, script 태그를 body의 바로 뒤에 작성하고 자바스크립트 파일에 DOM API를 사용한다면 DOM 생성이 완료되기도 전에 DOM이 변경되기에 이는 오류를 발생시킨다.
- 따라서 일반적으로 body 요소의 가장 아래에 자바스크립트 파일을 위치시킨다. 이는 자바스크립트가 실행되기 이전에 DOM 생성이 완료되어 렌더링되므로 페이지 로딩 시간이 단축된다.
script 태그의 async/defer 어트리뷰트
- HTML5부터 자바스크립트 파싱에 의한 DOM 생성이 블로킹되는 문제를 해결하기 위해 추가된 어트리뷰트이다.
- 공통점: HTML 파싱과 외부 자바스크립트 파일 로드가 비동기적으로 동시 진행된다.
async 어트리뷰트
- 자바스크립트 파일의 파싱과 실행이 자바스크립트 파일 로드가 완료된 직후 실행되어 이때, HTML 파싱이 중단된다.
defer 어트리뷰트
- 자바스크립트 파일의 파싱과 실행이 DOM 생성이 완료된 직후(HTML 파싱 완료된 후) 진행된다.
- DOM 생성 완료 이후 실행되어야 할 자바스크립트 파일에 적용하는 것이 좋다.