38. 브라우저 렌더링 과정

Jun_Gyu·2025년 3월 4일
0

한 발자국 더, JS

목록 보기
25/34
post-thumbnail

렌더링이란?

HTML, CSS, JS 문법으로 작성된 문서를 파싱하여, 브라우저에 사용자가 식별할 수 있도록 시각적으로 출력하는 것.

  • 파싱
    프로그래밍 언어의 문법에 맞게 작성된 텍스트 문서의 문자열을 토큰으로 분해하고, 토큰에 문법적 의미와 구조를 반영하여 파스트리 생성하는 일련의 과정을 이야기함.

1. 브라우저의 렌더링 과정

1) 브라우저는 렌더링에 필요한 리소스(HTML, CSS, 자바스크립트, 이미지, 폰트 등)를 요청하고,
서버로부터 응답을 받음.

2) 브라우저의 렌더링 엔진은 서버로부터 응답된 HTML, CSS를 파싱하여 DOM, CSSOM 생성하고 결합하여 렌더트리 생성

3) 브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 AST 생성하고, 바이트코드로 변환하여 실행

(이 때, 자바스크립트는 DOM API 통해 DOM과 CSSOM 변경 가능, 변경된 DOM과 CSSOM은 다시 렌더트리로 결합.)

4) 렌더트리를 기반으로 HTML 요소의 레이아웃 계산하고, 브라우저 화면에 HTML 요소 페인팅.


2. 요청과 응답

브라우저의 핵심 기능 === 필요한 리소스를 서버에 요청 & 서버로부터 응답을 받아 브라우저에 시각적으로 렌더링하는 것!

  • 브라우저가 제공하는 주소창을 통하여 서버로 요청을 전송.
  • 주소창에 URL을 입력할 시, URL 호스트 이름이 DNS를 통하여 IP주소로 변환되고, 해당하는 IP 주소의 서버로 요청을 전송.
  • 암묵적으로 서버는 루트 요청에 대해서 정적 파일인 index.html로 응답함.
  • JS나, 주소창을 통해서 서버에게 다른 정적파일을 요청할 수도 있음.

3. HTTP 1.1 & 2.0

HTTP란, 웹에서 브라우저 <-> 서버간의 통신을 위한 프로토콜을 이야기함.

  • HTTP/1.1 : 커넥션당 하나의 요청과 응답만 처리,
    리소스 요청이 개별적으로 전송되고 응답도 개별적으로 전송.
    -> 동시전송이 불가하기 때문에 요청할 리소스의 개수에 비례하여 응답 시간 증가.
  • HTTP/2 : 커넥션당 여러 개의 요청과 응답 가능
    -> 페이지 로드 속도가 HTTP 1.1 보다 대략 50% 빠름

4. HTML 파싱과 DOM 생성

* DOM : Document Object Model
브라우저가 이해할 수 있는 자료구조 -> html 문서를 파싱한 결과물

과정

1) 서버에 존재하던 HTML 파일이 브라우저의 요청에 의해 응답됨.
이때, 서버는 브라우저가 요청한 HTML 파일을 읽어 들여 메모리에 저장한 다음, 메모리에 저장된 바이트(이진수)를 응답.

2) 서버가 응답한 HTML 문서를 브라우저에서는 바이트 형태로 응답받음. 응답된 바이트 형태의 HTML 문서는 meta 태그의 charset 어트리뷰트에 의해 지정된 인코딩 방식을 기준으로 문자열로 변환되고, 브라우저에서는 확인하고 문자열로 변환.

3) 문자열로 변환된 HTML 문서를 읽어 들여 문법적 의미를 갖는 코드의 최소 단위인 토큰들로 분해.

4) 각 토큰들을 객체로 변환하여 노드를 생성함. 토큰의 내용에 따라서 문서 노드나 요소 노드, 텍스트 노드 등등으로 생성됨. 이후에 노드는 DOM을 구성하는 기본 요소가 된다.

5) HTML 문서는 HTML 요소들의 집합으로 이루어지며 HTML 요소는 중첩 관계를 가진다. 이 때, HTML 요소 간에는 중첩 관계에 의해 부자 관계가 형성됨. 이러한 HTML 요소 간의 부자 관계를 반영하여 모든 노드들을 트리 자료구조로 구성함. 이 노드들로 구성된 트리 자료구조를 DOM이라 부른다.


5. CSS 파싱과 CSSOM 생성

  • 렌더링 엔진은 HTML을 순차적으로 파싱하며 DOM을 생성하다가, CSS를 로드하는 style태그나 link태그를 만나면 DOM 생성을 일시 중단하고, CSS를 파싱하여 CSSOM 생성함.

  • CSS 파싱을 완료 한 후, HTML 파싱이 중단된 지점부터 다시 HTML 파싱.


6. 렌더트리 생성

DOM과 CSSOM은 렌더링을 위한 렌더트리로 결합됨.

* 렌더트리 : 렌더링을 위한 트리구조의 자료구조로, 브라우저 화면에 렌더링 되는 노드만 표시함.(비표시되는 노드들은 포함 X) 각 HTML 요소의 레이아웃을 계산하는데 사용되고 브라우저 화면에 픽셀을 렌더링하는 페인팅 처리에 입력됨.

리렌더링의 발생 원인

1) 자바스크립트에 의한 노드 추가 및 삭제

2) 브라우저 창의 리사이징에 의한 뷰포트 크기 변경

3) HTML 요소의 레이아웃에 변경을 발생시키는 스타일 변경


리플로우/리페인팅

DOM과 CSSOM을 변경하는 DOM API가 사용된 경우, 변경된 DOM과 CSSOM은 다시 렌더트리로 결합되고,

변경된 렌더트리를 토대로 레이아웃과 페인트 과정을 거쳐 화면에 다시 렌더링 된다.

  • 리플로우 : 레이아웃 계산을 다시 하는 것을 말하며,
    레이아웃에 영향을 주는 변경이 일어난 경우에 한해서 실행한다.

  • 리페인트 : 재결합된 렌더트리를 기반으로 다시 페인트 하는 것이다.

리플로우리페인트가 순차적으로 동시에 일어나는것은 아니며,
레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 다시 일어나게 된다.


7. 자바스크립트 파싱에 의한 HTML 파싱 중단

렌더링 엔진과 자바스크립트 엔진은 직렬적으로 파싱을 수행하며, 브라우저는 동기적, 순차적으로 수행한다.

-> script 태그의 위치에 따라 HTML 파싱이 블로킹 되면 DOM 생성이 지연될 수 있음!

따라서 script 태그의 위치는 중요하며,
블로킹 현상을 예방하기 위해서는 body 요소의 가장 아래에 자바스크립트를 위치 시키는 것이 바람직함.

  • DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작하면 에러 발생할 수 있음.

자바스크립트 로딩 파싱 실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 않 페이지 로딩시간이 단축됨.


8. script 태그의 async/defer 어트리뷰트

JS 파싱으로 인한 DOM 생성 중단 현상을 극복하기 위해 async/defer 어트리뷰트HTML5부터 추가되었다.

async/defer 공통점

async/defer 어트리뷰트는 src 어트리뷰트를 통해 외부 자바스크립트 파일을 로드하는 경우에만 사용,

async/defer 어트리뷰트를 사용하면 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 진행됨.

async/defer 차이점 :

자바스크립트의 실행 시점이 서로 다르다.

  • async 어트리뷰트 : 자바스크립트의 파싱과 실행은 자바스크립트 파일 로드가 완료된 후 진행, 이 때 HTML 파싱 중단

여러개의 script 태그에 async 어트리뷰트 지정하면 script 태그 순서와 상관없이, 로드가 완료된 자바스크립트부터 실행 -> 순서보장 x

  • defer 어트리뷰트 : 자바스크립트의 파싱과 실행은 HTML 파싱이 완료된 직후 진행, DOM 생성이 완료된 이후 실행되어야 할 자바스크립트에 유용함.

따라서,
순서의 보장이 필요하다면 defer, 병렬적인 작업을 위한 script 태그에는 async 어트리뷰트를 지정하면 되겠다.

profile
시작은 미약하지만, 그 끝은 창대하리라

0개의 댓글