브라우저 렌더링 과정

나혜수·2023년 2월 3일
0

자바스크립트 실전

목록 보기
3/19

렌더링

렌더링이란 HTML, CSS, 자바스크립트 등 개발자가 작성한 문서가 브라우저에서 출력되는 과정을 말한다. 브라우저는 렌더링을 수행하는 렌더링 엔진을 가지고 있다. 크롬은 블링크(Blink), 사파리는 웹킷(Webkit), 파이어폭스는 게코(Gecko)라는 렌더링 엔진을 사용한다.

브라우저의 핵심 기능은 필요한 리소스(HTML, CSS, 자바스크립트, 이미지, 폰트 등)를 서버에 request 요청하고 서버로부터 response 응답받아 브라우저에 시각적으로 렌더링 하는 것이다.


렌더링 과정

1. Parsing

HTML 파일을 해석하여 DOM Tree를 구성하는 단계이다.
렌더링 엔진은 HTML을 처음부터 한 줄씩 순차적으로 파싱하여 DOM을 생성해 나간다. DOM을 생성해 나가다가 CSS를 로드하는 link or style 태그를 만나면 DOM 생성을 일시 중단한다. 그리고 CSS파일을 서버에 요청하여 HTML과 동일한 파싱 과정을 거치며 CSSOM (CSS Object Model) Tree를 구성한다. 파싱 완료 후, HTML 파싱이 중단된 지점부터 다시 DOM을 구성해 나간다.

DOM API

DOM은 HTML 문서의 구조, 정보뿐만 아니라 HTML 요소와 스타일 등을 변경할 수 있는 프로그래밍 인터페이스로서 DOM API를 제공한다. 즉, 자바스크립트 코드에서 DOM API를 사용하면 이미 생성된 DOM을 동적으로 조작할 수 있다.

API
API (Application Programming Interface)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다.

예를 들어 alert('Hello World!')를 실행하면 경고창으로 'Hello World!' 가 나온다. 이때 이 경고창의 규격 (크기, 닫기 버튼, 위치 선정 등)은 다 브라우저에서 제공해준 것이고 내용만 우리가 지정한 'Hello World!' 이다. 즉, 우리는 웹 API를 이미 쓰고 있는 것이다. 사실 우리가 코딩하면서 쓰는 함수들 거의 전부가 API라고 해도 과언이 아니다. 요즘 세상에 기계어로 직접 코딩하는 사람은 거의 없기 때문이다.

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

CSS 렌더링 과정과 비슷하게 script 태그를 만나면 자바스크립트 파일을 서버에 요청하고 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘긴다. 이후 자바스크립트 파싱이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML 파싱이 중단된 지점부터 다시 HTML 파싱을 시작하여 DOM 생성을 재개한다.
❗자바스크립트 파싱과 실행은 브라우저 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.

렌더링 엔진과 자바스크립트 엔진은 직렬적(동기적)으로 파싱을 수행한다. 즉, 위에서 아래 방향으로 순차적으로 HTML, CSS, 자바스크립트를 파싱하고 실행한다.

따라서 script 태그 위치에 따라 HTML 파싱이 블로킹(파싱이 중단)되어 DOM 생성이 지연될 수 있다. 또한 DOM이 완성되지 않은 상태에서 DOM API를 사용하는 자바스크립트가 DOM을 조작하면 에러가 발생할 수 있다. 이러한 이유로 body 요소의 가장 아래에 자바스크립트를 위치시킨다. 이렇게 하면 HTML 파일이 먼저 파싱, 실행되어 페이지 로딩 시간이 단축된다.

블로킹을 해결하는 다른 방법은 script 태그의 async/defer 속성을 이용하는 것이다. 이 속성은 scr로 외부 자바스크립트 파일을 불러오는 경우에만 사용 가능하고, 인라인 자바스크립트로는 사용이 불가하다.

  • async
    HTML 파싱과 JS 파일 로드를 병렬적(비동기적)으로 진행한다. 여러 개의 script 태그에 async를 지정하면 태그 순서와 상관없이 먼저 로드가 완료된 순서부터 실행된다. 따라서 순서가 보장되지 않는다.

  • defer
    HTML 파싱이 완료된 직후 JS 파일을 파싱, 실행한다.

2. Style

DOM Tree와 CSSOM Tree를 매칭시켜서 Render Tree를 구성한다. Render Tree는 실제로 화면에 그려질 Tree이다.
예를 들어 Render Tree를 구성할때 visibility : hidden은 요소가 공간을 차지하고 보이지만 않기 때문에 Render Tree에 포함되지만, display : none은 Render Tree에서 제외된다.

3. Layout

Render Tree를 화면에 어떻게 배치해야 할 것인지 각 노드의 정확한 위치와 크기를 계산한다.
루트부터 노드를 순회하면서 노드의 정확한 크기와 위치를 계산하고 Render Tree에 반영한다.
%와 같은 상대적인 값들은 Layout 단계에서 절대적인 픽셀 단위로 변환한다.

4. Paint

Layout 단계에서 계산된 값을 이용해 Render Tree의 각 노드를 화면상의 실제 픽셀로 변환한다. 이때 픽셀로 변환된 결과는 하나의 레이어가 아니라 여러 개의 레이어로 관리된다. 생성된 레이어를 합성하여 실제 화면에 나타낸다. 우리는 화면에서 웹 페이지를 볼 수 있다.


Reflow, Repaint

위의 렌더링 과정을 거친 뒤 최종적으로 페이지가 그려진다고 해서 렌더링 과정이 다 끝난 건 아니다. 어떠한 액션, 이벤트에 따라 html 요소의 레이아웃 수치를 수정하면 Layout 과정을 다시 수행하게 되는데 이를 Reflow라고 한다. 이후 Reflow된 Render Tree를 다시 화면에 그려주는 Paint 단계가 다시 수행되는데 이를 Repaint라고 한다.
무조건 Reflow가 일어나야 Repaint가 일어나는건 아니다. background-color, visibility와 같이 레이아웃에는 영향을 주지 않는 스타일 속성이 변경되었을 때는 Repaint만 수행한다.

profile
오늘도 신나개 🐶

0개의 댓글