브라우저의 렌더링 과정

terry yoon·2021년 10월 3일
0
post-thumbnail

프로트엔드 개발자는 기본적으로 웹 페이지를 개발하는 사람이다. 따라서 브라우저가 어떻게 화면을 랜더링하는지에 대한 기본적인 이해는 필수이다. 이번 글을 통해서 브라우저의 서버 요청과 응답을 받고, 서버 자원을 통해 웹 페이지를 랜더링하는 과정을 정리하고자 한다.

브라우저의 랜더링 과정은 크게 2가지로 나눠서 정리할 수 있다.

1) 서버 사이드 과정 
2) 클라이언트 사이드 과정 

서버와 요청과 응답 - 서버 사이드

서버 요청

브라우저의 핵심 기능은 서버에 자원을 요청하여 이를 화면에 랜더링하는 것이라고 할 수 있다. 따라서 우선 브라우저가 화면 랜더링에 필요한 자원을 서버에 요청하여 이를 다운 받는 과정이 필요합니다.

브라우저는 이를 위해 주소창을 제공하고, 문자열 형태의 URL을 전송합니다. 이 URL은 일종의 웹 페이지 서버 식별자라고 할 수 있습니다. 즉, 자신의 고유한 URL을 통해서 어떤 서버에 자원을 요청할지 알 수 있습니다.

더 자세히 표현하면, 주소창에 입력된 URL은 중간 서버인 DNS에서 IP 주소로 변환 됩니다. DNS는 Domain Name System으로 해당 URL을 해석하여 해당 URL이 있는 IP 주소로 해석하여 클라이언트에 전달하는 역할을 합니다. 클라이언트는 해당 IP 주소를 통해 원하는 서버로 접근하여 자원을 요청하여 다운로드 받게 됩니다.

서버 응답

일반적으로 루트 요청(스킴, 호스트로만 구성된 요청)을 할 경우, 정적 파일인 index.html 파일을 서버로부터 다운로드 받는 것이 일반적입니다.

(schem) https:// (host) www.example.com

물론 index.html 이외의 세부적인 자원을 요청받기 원한다면 루트요청 뒤 path 에 요청할 파일의 디렉토리와 파일 이름을 붙혀서 전달할 수도 있습니다.

서버는 해당 자원을 요청받으면 해당 자원을 바이트 형태(2진수)로 클라이언트에게 전달합니다.

클라이언트 과정

DOM 파싱 과정

서버로부터 전달받은 데이터는 바이트 형태로 전달받았기 때문에, 해당 데이터를 렌더링 엔진이 이해할 수 있는 문자열 형태로 인코딩하게 됩니다. 이때 인코딩 기준은 서버로부터 전달받은 응답 헤더 내의 인코딩 방식에 따라 인코딩 되게 됩니다.

응답 헤더란 HTTP 헤더의 일종으로, HTTP 헤더에는 클라이언트와 서버 간의 응답과 요청에서 부가적인 정보를 전달하는 역할을 담당한다.

문자열로 인코딩 된 후, 해당 문자열을 다시 최소 문법 단위인 토큰(Token) 형태로 나누고 이 토큰을 묶어 객체인 노드를 형성합니다. 노드는 HTML 파일을 파싱하면서 생기는 다양한 타입의 객체입니다.

해당 객체는 중첩 관계에 따라 부자 관계(parent-child)를 형성하고, 이 관계를 명시한 트리 자료 구조가 바로 DOM이라고 합니다.

CSSOM 과 자바스크립트 파싱과정

CSSOM은 CSS 파일을 파싱하여, DOM 과 유사하게 트리 자료구조로 생성되게 됩니다. 랜더링 엔진은 HTML을 파싱하는 과정에서 style 태그 또는 link 태그를 만나게 되면, DOM 구성을 중단하고 서버에게 css 파일을 요청하여 이를 파싱한 후 CSSOM을 생성하게 됩니다. 이후 CSSOM 생성이 완료되면, DOM 생성을 재게하게 됩니다.

자바스크립트 파일 역시 script 태그를 만날 경우, DOM 트리 생성을 중단한 후 자바스크립트 파싱을 위한 작업을 진행합니다.
다만 css 파일과 달리 자바스크립트는 랜더링 엔진이 아닌, 자바스크립트 엔진에 의해 파싱이 이뤄지기 때문에 랜더링 엔지으로부터 자바스크립트 엔진으로 제어권이 이동합니다.

자바스크립트 엔진 파싱 과정

자바스립트 엔진은 자바스크립트 소스코드를 토큰으로 변환하여 다른 파싱과 같이 트리 자료구조인 AST(추상적 구문 트리)를 생성한다. 일반적으로 파서(Parser)는 구문 분석기라고 불리며 이 파서에 이해 파싱이 수행되어 AST가 생성된다.

이렇게 변환된 AST를 인터프리터가 이해할 수 있는 중간 언어(intermediate)로 변환하여 자바스크립트를 실행하게 된다.

이후 자바스크립트 실행이 완료되면 다시 제어권은 렌더링 엔진으로 이동하여 DOM 구성을 완료한다.

랜더 트리 생성 및 레이아웃, 페인트

DOM과 CSSOM을 결합하여 실제 화면에 노출될 노드들로만 구성된 랜더 트리를 형성한다. 이 랜더 트리를 이용해 각 노드가 화면 상에어 어디에 어떤 크기로 랜더링 될지 계산하는 과정(Layout)을 거친 후 실제 화면에 페인트(Paint)를 하게 되면 랜더링이 완료 된다.

리플로우와 리페인트

위에서 살펴본 DOM 트리는 웹 페이지 노드에 대한 정보 뿐만 아니라 DOM 의 상태를 변경(노드의 추가, 변경 및 삭제 등)을 할 수 있는 DOM API를 제공한다. 따라서 자바스크립트를 이용해 DOM 트리가 생성된 이후에 동적으로 이를 변경할 수 있다.

하지만, 이런 DOM 구조를 변경하는 것은 리플로우 리페인트를 발생하여 자칫 성능저하를 발생시킬 수 있다. 위의 랜더링 과정에서 보았듯이, DOM 구조를 변경하게 되면, 랜더링 트리를 시작으로 새롭게 레이아웃과 페인트 과정을 반복해야 하기 때문이다.

따라서 최대한 리플로우와 리페인트가 발생하지 않도록 하는 것이 성능에 있어 중요하다.

profile
배운 것을 기록하는 FrontEnd Junior 입니다

0개의 댓글