Jaeilit

브라우저 렌더링 본문

TIL

브라우저 렌더링

Jaeilit 2023. 6. 7. 11:00
728x90

앞에 글에서 URL 을 입력했을 때 DNS 서버에서 IP 를 반환받아 해당 IP 주소의 서버에서 리소스를 받아오는 것까지 알아봤습니다.

받아온 리소스를 어떻게 브라우저에 렌더링하는지 알아보려고 합니다.

 

브라우저 렌더링 과정

 

파싱

브라우저는 렌더링 엔진을 통해서 HTML 을 파싱하기 시작합니다.

파싱하던 중 Javascript 코드인 script 태그를 만나게 됩니다.

script 태그를 만난 렌더링 엔진은 파싱을 일시중단하고 JS 리소스를 다운로드 하고, JS 를 파싱하기위해 제어권을 JS 엔진에게 넘깁니다.

HTML 을 동기적으로 파싱하고 있었기 때문에 JS 엔진에게 넘긴 script 태그도 끝날때까지 기다려야합니다.

 

이 부분에서 지연이 발생할수있고 JS가 돔을 조작하는 이벤트를 가지고 있다면 script 태그 위치에 따라 에러를 발생시킬수도 있습니다.

이러한 이유로 script 태그는 body 태그 맨 하단에 위치시키는 것이 좋고, 아니라면 async, defer 속성을 통해서 비동기적으로 실행시킬수 있습니다.

 

async 과 defer 의 차이

 

두 속성이 비슷하지만 차이가 있습니다.

두 속성 모두 script 를 다운로드 받는 것은 html 파싱 도중에 비동기적으로 실행하지만

async html 파싱 도중에 리소스 다운로드가 끝나면 스크립트를 실행하고

defer은 html 파싱이 끝난 후에 실행시킵니다.

 

이런 특징 때문에 defer 은 dom 조작과 관련 된 스크립트에 사용하는 것이 좋고

async 는 돔과 관련없이 html 파싱 도중에 언제라도 실행되도 상관없고 순서가 보장되지 않아도 될 때 사용하는 것이 좋습니다.

 

또 body 태그 맨 끝에 사용하게 되면 async 나 defer는 html 이 파싱이 끝난 후 script 태그를 실행하는 것이라 크게 의미가 없습니다.

 

렌더 트리 구성

가장 먼저 HTML 는 DOM 트리를 생성하고, CSSOM 트리를 생성합니다.

DOM과 CSSOM 이 결합하여 렌더트리를 구성합니다.

Layout

렌터트리를 구성한 다음 Layout 단계를 거치게 됩니다.

Layout 단계에서는 돔을 그리기 위해 요소의 정확한 위치와 크기를 픽셀 단위로 계산하게 됩니다.

만약 % 가 들어간 단위가 있다면 계산하여 픽셀단위로 변경합니다.

 

페인팅

요소의 위치와 크기의 계산이 완료되면 화면에 요소들을 그리게 됩니다. 이 단계를 페인팅이라고 합니다.

 

리플로우와 리페인트

만약 페이지에서 DOM 에 대한 이벤트가 일어나

면 렌더트리 생성과 레이아웃 과정을 다시 수행하게 됩니다.

이 과정을 Reflow 라고 부릅니다.

 

예를들어 HTML 요소가 추가되는 이벤트가 발생되면 렌더트리를 다시 구성해야하므로 Reflow 가 발생합니다.

그리고 width, height, margin, padding, font-size 등 Layout 과정에 속하는 DOM의 위치와 크기를 계산해야하는 작업을 필요로 하는 이벤트가 발생하면 Reflow가 발생합니다.

 

하지만 Reflow 가 필요하지않고 Repaint 만 하는 경우가 있습니다.

앞서 위에서 페인팅(Painting) 이라고 소개한 부분은 그리는 부분이라고 말씀드렸는데,

HTML 요소의 추가가 없거나 위치와 크기를 다시 계산해야하는 일이 없는 이벤트가 일어나는 경우에는 Repaint 만 하게 됩니다.

 

예를들면 backgorund-color 또는 color, border-style, border-radius 정도로 요소의 크기와 위치관계 없이 스타일만 변경되는 경우에는 Repaint 만 일어나게 됩니다.

 

728x90