(펌)개념 정리

브라우저 랜더링 과정

ble194 2022. 11. 21. 19:41

브라우저 렌더링 과정

 

 1. 파싱, 렌더 트리 생성

파싱(Parsing)은 구문 분석이라고도 불리며, 일련의 문자열을 의미 있는 토큰(token)으로 분해하고 토큰 간의 위계 관계를 분석해 구조를 결정하는 것이다.

파싱 과정
· 변환 : 문서를 가져와서 지정된 인코딩 방식으로 읽는다.
· 토큰화 : 표준에 맞춰 지정된 태그들을 토큰화한다.
· 렉싱(lexical analysis) : 토큰을 해당 속성 및 규칙을 정의하는 노드로 만든다.
· 트리 생성 : root 노드를 기준으로 생성된 노드들의 계층을 연결한다.
(좌) HTML 파싱 과정 (우) 토큰화 과정

 

1-1. HTML 파싱

렌더러 프로세스의 메인 스레드가 HTML을 파싱해 DOM(Document Object Model)으로 변환한다.

파싱의 최종 결과로 DOM 트리가 만들어지며, 최상위 노드(root)는 <html>이다.

DOM은 일종의 인터페이스로 해당 요소를 나타내는 노드, 노드의 속성을 나타내는 프로퍼티, 이를 조작할 수 있는 여러 메서드를 담아 구조화한 객체로 표현한다.

DOM을 통해 자바스크립트 같은 여러 프로그래밍 언어로 해당 요소에 접근해 해당 구조나 내용, 스타일을 변경할 수 있다. DOM이 없다면 자바스크립트는 웹 페이지에 대한 정보는 얻을 수 없다.

<html>
  <body>
    <p>
      Hello World
    </p>
    <div> <img src="example.png"/></div>
  </body>
</html>
// DOM API 사용 예시
// p 태그의 내용이 변경된다.
let paragraph = document.querySelector('p');
paragraph.textContent = "Hi :)";

⚠️ <img>, <link> 같은 태그를 만나면 미리 브라우저 프로세스의 네트워크 스레드로 요청을 보낸다.

⚠️ <script> 태그를 만나면 브라우저는 HTML 파싱을 중단한다. 자바스크립트에는 문서 전체의 구조를 바꿀 수 있는 메서드, 프로퍼티가 존재하기 때문이다. 자바스크립트 파싱이 끝난 후 HTML 파싱이 재개된다. 만약 스크립트 파일에서 문서 조작이 이루어지지 않는다면 <script> 태그에 async나 defer 속성을 지정해, HTML 파싱이 중단되지 않도록 설정할 수 있다.

💡 async, defer 속성?
· async : HTML 문서가 완전히 다운로드되지 않은 상태라도 병렬적으로 스크립트가 로드 및 평가된다.
· defer : 스크립트가 모두 로드 및 평가된 이후에 DOMContentLoaded 이벤트가 발생하도록 한다.

DOM 트리

 

1-2. CSS 파싱

HTML 파싱 과정에서 <link> 태그를 만나면, 해당 CSS 리소스를 가져온다.

HTML과 비슷하게 CSS 역시 토큰화, 노드 생성을 거쳐 CSSOM(CSS Object Model)이라는 트리 구조를 가진다.

CSSOM은 자바스크립트에서 CSS를 조작할 수 있게 해주는 API 집합이다.

// CSSOM API 사용 예시
document.body.style.background = 'lightblue';

CSSOM 트리

 

1-3. 렌더 트리(Render Tree) 만들기

렌더 트리는 DOM 트리와 CSSOM 트리가 결합되어 생성된다.

각 노드는 렌더 객체로 이루어져 있으며 렌더 객체는 보이는 노드만을 포함한다.

렌더 트리 생성 과정
1. <html> 태그와 <body> 태그를 처리하며 렌더 트리 루트를 구성한다.
2. DOM 트리를 순회하며 최상위 노드(<html>)부터 보여지지 않는 노드(<link>, <script>, <meta> 등)를 생략한다.
3. display: none처럼 CSS로 숨겨지는 노드 또한 트리에서 생략한다.
4. float나 position 같은 속성을 사용했을 경우 흐름에서 벗어나 실제 그려지는 위치로 렌더 객체가 이동한다.
5. 화면에 나타나는 노드에 CSSOM 규칙을 찾아 일치하는 스타일을 적용한다.

렌더 트리

 

 

렌더 트리 생성

위에서 생성된 DOM 과 CSSOM 트리를 렌더 트리로 결합한다. 렌더 트리는 렌더링을 위한 트리 구조의 자료구조로 브라우저 화면에 렌더링되는 노드만으로 구성된다.

 

Layout

Layout 단계는 브라우저의 뷰포트(Viewport) 내에서 각 노드들의 정확한 위치와 크기를 계산합니다. 풀어서 얘기하자면 생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느위치에 어느크기로 출력될지 계산하는 단계라고 할 수 있습니다. Layout 단계를 통해 %, vh, vw와 같이 상대적인 위치, 크기 속성은 실제 화면에 그려지는 pixel단위로 변환됩니다.

 

Viewport 에 상대적인 요소 연산 - 출처 :  http://bit.ly/3137pmh

여기서 뷰포트(Viewport)란 그래픽이 표시되는 브라우저의 영역, 크기를 말합니다.

뷰포트는 모바일의 경우 디스플레이의 크기, PC의 경우 브라우저 창의 크기에 따라 달라집니다. 그리고 화면에 그려지는 각 요소들의 크기와 위치는 %, vh, vw와 같이 상대적으로 계산하여 그려지는 경우가 많기 때문에 viewport 크기가 달라질 경우 매번 계산을 다시해야 합니다.

 

Paint

Layout 계산이 완료되면 이제 요소들을 실제 화면을 그리게 됩니다. 이전 단계에서 이미 요소들의 위치와 크기, 스타일 계산이 완료된 Render Tree 를 이용해 실제 픽셀 값을 채워넣게 됩니다. 이 때 텍스트, 색, 이미지, 그림자 효과등이 모두 처리되어 그려집니다.

 

렌더 트리를 만들며 DOM 요소의 위치, 스타일 등을 계산했다. 하지만 같은 위치에 그려지는 여러 노드가 있다면 어떤 순서로 그려야 할까? 만약 z-index, float, position 같은 CSS 프로퍼티를 이용해 레이어의 순서를 변경한다면, 렌더 트리의 순서가 레이어의 순서와 일치하지 않을 것이다.

페인트 단계에서는 렌더 트리를 순회하며 레이어를 만들고, 레이어의 배경, 테두리, 텍스트, 그려지는 순서, 레이어 간의 순서 등 그려지는 과정을 기록한다.

 

이 때 처리해야 하는 스타일이 복잡할수록 Paint 단계에 소요되는 시간이 늘어나게 됩니다. 간단한 예시로 단순한 단색 background-color의 경우 paint 속도가 빠르지만 그라데이션이나 그림자 효과등은 painting 소요시간이 비교적 더 오래 소요됩니다.

 

 

합성(Compositing)

그려질 요소들의 순서, 스타일, 위치 등의 정보를 화면의 픽셀로 변환하는 것을 래스터화(rasterizing)라고 한다.

합성은각 레이어를 분리해서 래스터화한 뒤 브라우저에서 페이지의 크기, 뷰포트에 맞게 합성해 화면으로 나타내는 과정이다.

 

출처 - https://sunyong-01.tistory.com/48