[JavaScript] 브라우저의 렌더링 과정

백괴·2021년 12월 26일
3

자바스괴립트

목록 보기
1/5
post-thumbnail

잘못 된 내용에 대한 지적은 언제든 환영입니다.

브라우저 렌더링 과정

브라우저는 서버와의 데이터 통신 이후, 해당 데이터를 사용자에게 보여주기 위한 렌더링을 수행한다.
1. 서버로부터 자원을 요청한 뒤 응답받기
2. HTML 파싱 후 DOM 생성하기
3. CSS 파싱 후 CSSOM 생성하기
4. 렌더 트리 생성하기
5. JS 파싱 후 AST(추상 구문 트리) 생성하기
6. 렌더 트리를 통해 HTML을 브라우저에 레이아웃 후 페인팅

1. 서버로부터 자원을 요청한 뒤 응답받기

  • 브라우저는 URL을 입력받으면, DNS(도매인 서버)를 통해 IP주소로 변환받아 해당 IP 주소를 갖는 서버에 요청을 전달한다.

2. HTML 파싱 후 DOM 생성하기

  • HTML은 서버로부터 바이트 형태로 전달받게 되며, 이후 문자열로 변환한다.
  • 문자열로 변환 된 HTML은 각각 토큰으로 분해된다.
  • 토큰으로 분해 된 HTML은 각각 노드 객체로 분해되며, 각각의 노드 객체가 부모-자식 관계를 형성하며 트리 형태의 자료구조인 DOM을 형성한다.

3. CSS 파싱 후 CSSOM 생성하기

  • CSS 또한 파싱 과정이 바이트 ➡️ 문자열 ➡️ 토큰 ➡️ 노드로 이루어진다.
  • 각각의 노드는 부모-자식 관계를 형성하며 트리 형태의 자료구조인 CSSOM을 형성한다.
  • HTML 파싱 중, CSS를 의미하는 link 태그나 style 태그를 만날 경우 블로킹되어 CSSOM 생성으로 넘어간다.
  • CSSOM 생성이 마무리되면, 블로킹 된 시점부터 다시 HTML 파싱을 진행한다.

4. 렌더 트리 형성

  • 렌더 트리란? 렌더링에 필요한 트리 자료 구조이다.
  • DOMCSSOM으로 이루어져 있다.
  • 화면에 렌더링되는 노드만으로 구성된다. 화면에 렌더링되지 않는 display: none이나 meta 태그 등은 렌더 트리를 구성하지 않는다.

5. JS 파싱 후 AST 생성

  • AST란? 추상 구문 트리를 말하는 것이며, 이를 기반으로 인터프리터가 바이트코드(가상 머신이 이해할 수 있는 중간 레벨의 코드)를 생성한다.
  • HTML 파싱 중, JS를 의미하는 script 태그를 만나게 되면 블로킹되어 제어권을 JS엔진에게 넘겨주어 JS 파싱으로 넘어간다.
  • AST 생성 과정
    1. JS코드는 각각의 의미를 갖는 토큰으로 분해된다.
    1. 각 토큰은 서로 결합하여 AST를 형성한다.
    2. AST는 바이트코드로 변환되어 인터프리터가 실행한다.

6. 렌더 트리를 통해 HTML을 브라우저에 레이아웃 후 페인팅

  • 렌더 트리는 HTML 요소의 레이아웃 계산페인팅 처리에 이용된다.
  • JS에 의해 노드가 추가되거나 브라우저 창이 리사이징되었을 경우 리플로팅(재 레이아웃) 및 리페인팅(재 페인팅)이 일어난다.
    (레이아웃이 변경되는 사항이 없을 경우 리플로팅은 생략된다.)

JS 파싱에 의한 HTML 블로킹

  • 위에서 설명했다시피, HTML 파싱은 script 태그를 만나면 블로킹되어 렌더링 엔진에서 JS엔진에게 제어권을 넘겨주게 된다.
  • 스크립트는 동기적 파싱(위에서 아래로 파싱)이 이루어지기 때문에, HTML 파싱이 script 태그의 위치에 따라 지연될 수 있다.
  • 만약 JS 코드가 HTML 노드를 생성할 경우, HTML 파싱이 완료되어있어야 한다.
    👉 따라서 script 태그는 되도록이면 body 태그 맨 아래에 위치하는 편이 좋다.

async와 defer 어트리뷰트

  • script 태그를 body 태그 맨 아래에 위치시키더라도, JS 코드 파싱중에 사용자가 웹에 상호작용을 시도(버튼을 누르기, 텍스트 입력) 시 정상적으로 작동하지 않는다.
  • async, defer 어트리뷰트를 통해 JS 코드를 비동기적으로 불러옴으로써 DOM 렌더링의 블로킹을 방지할 수 있다.
  • async
    • JS 파일 로딩을 비동기적으로 처리한다.
    • JS 파일 로딩이 끝난 순서대로 파싱 및 실행이 이루어지며, 이 경우 HTML 파싱이 블로킹 처리되기에 순서가 보장되지 않는다.
  • defer
    • async와 마찬가지로 JS 파일 로딩을 비동기적으로 처리한다.
    • JS 코드의 파싱 및 실행DOM 생성 이후에 실행된다.

References
"모던 자바스크립트 Deep Dive" .이응모

0개의 댓글