브라우저의 핵심 기능은 사용자가 참조하고자 하는 웹페이지를 서버에 요청(Request)하고 서버의 응답(Response)을 받아 브라우저에 표시하는 것이다. 브라우저는 서버로부터 HTM, CSS, Javascript, 이미지 파일 등을 응답받는다. HTML, CSS 파일은 렌더링 엔진의 HTML 파서와 CSS파서에 의해 파싱(Parsing)되어 DOM, CSSOM 트리로 변환되고 렌더 트리로 결합된다. 이렇게 생성된 렌더 트리를 기반으로 브라우저는 웹 페이지를 표시한다.
브라우저의 기본 구조
- 사용자 인터페이스 : 여기에는 주소 표시줄, 뒤로/앞으로 가기 버튼, 북마크 메뉴 등이 포함된다. 요청한 페이지가 표시되는 창을 제외한 브라우저의 모든 부분이 표시된다.
- 브라우저 엔진 : UI와 렌더링 엔진 간의 작업을 마샬링(한 객체의 메모리에서 표현방식을 저장 또한 전송에 적합한 다른 데이터 형식으로 변환하는 과정)한다.
- 렌더링 엔진 : 요청된 콘텐츠 표시를 담당한다. 예를 들어 요청된 콘텐츠가 HTML인 경우 렌더링 엔진은 HTML 및 CSS를 구문 분석하고 구문 분석된 콘텐츠를 화면에 표시한다.
- 네트워킹 : HTTP 요청과 같은 네트워크 호출의 경우 플랫폼에 독립적인 인터페이스 뒤에서 서로 다른 플랫폼에 대해 서로 다른 구현을 사용한다.
- UI 백엔드 : 콤보 상자 및 창과 같은 기본 위젯을 그리는 데 사용된다. 이 백엔드는 플랫폼에 고유하지 않은 일반 인터페이스를 노출한다. 그 아래에서 운영 체제 사용자 인터페이스 방법을 사용한다.
- JavaScript 인터프리터 : JavaScript 코드를 구문 분석하고 실행하는데 사용된다.
- 데이터 저장소 : 이것은 지속성 계층이다. 브라우저는 쿠키와 같은 모든 종류의 데이터를 로컬에 저장해야 할 수도 있다. 브라우저는 또한 localStorage, IndexedDB, WebSQL 및 FileSystem과 같은 저장소 메커니즘을 지원한다.
렌더링 엔진
HTML, XML, 이미지 등 요청받은 내용을 브라우저 화면에 표시하는 엔진이다.
- Trident : Internet Explorer
- Gecko : Firefox
- WebKit : Safari
- Blink : Chrome, Edge, Opera
랜더링 엔진 동작 과정
- HTML 마크업을 처리하여 DOM 트리를 생성한다
- CSS 마크업을 처리하여 CSSOM 트리를 생성한다.
- DOM 트리와 CSSOM 트리를 결합하여 렌더링 트리를 생성한다.
- 렌더링 트리 레이아웃 : 각 노드에 대해 화면에서의 정확한 좌표와 크기를 계산한다.
- 랜더 트리 페인팅 : UI 백엔드에서 렌더링 트리의 각 노드를 그린다.
렌더링 엔진 동작과정은 점진적이며, 더 나은 사용자 경험을 위해 렌더링 엔진은 가능한 빨리 화면에 내용을 표시하려고 한다. 렌더 트리를 빌드하고 레이아웃하기 시작 전에 모든 HTML이 구문 분석될 때까지 기다리지 않는다. 콘텐츠의 일부가 구문 분석되고 표시되는 동안 프로세스는 네트워크에서 계속 들어오는 나머지 콘텐츠로 진행된다.
- WebKit 기본 흐름
- Mozilla의 Gecko 렌더링 엔진 주요 흐름(3.6)
1. HTML 마크업 파싱과 DOM 트리 구축
Parsing
서버로부터 전송받은 문서의 문자열을 브라우저가 코드를 이해하고 사용할 수 이쓴 구조로 변환하는 것을 의미한다.
파싱 결과는 보통 문서 구조를 나타내는 노드 트리로 파싱 트리(parsing tree) 또는 문법 트리(syntax tree)라고 부른다.
DOM(Document Object Model)
HTML 문서의 객체 표현이고 외부를 향하는 자바 스크립트와 같은 HTML 요소의 연결 지점이다. 트리의 최상위 객체는 Document이다.
DOM은 마크업과 1:1의 관계를 맺는다.
<html>
<body>
<p>Hello World</p>
<div><img src="example.png" /></div>
</body>
</html>
위의 마크업을 아래와 같은 DOM 트리로 변환할 수 있다.
2. CSS 마크업 파싱과 CSSOM 트리 구축
HTML과는 다르게 CSS는 문맥 자유 문법이다.
각 CSS 파일은 스타일 시트 객체로 파싱되고 각 객체는 CSS 규칙을 포함한다. CSS 규칙 객체는 선택자와 선언 객체 그리고 CSS 문법과 일치하는 다른 객체를 포함한다.
3. DOM+ CSSOM 랜더 트리 구축
DOM 트리가 구축되는 동안 브라우저는 렌더 트리를 구축한다. 표시해야 할 순서와 문서의 시각적인 구성 요소로써 올바른 순서로 내용을 그려낼 수 있도록 한다.
파이어폭스는 이 구성 요소를 "frames"라고 부르고, Webkit은 "renderer" 또는 "render object 라는 용어를 사용한다.
렌더러는 자신과 자식 요소를 어떻게 레이아웃하고 페인팅 해야하는지 알고 있다.
DOM 트리와 렌더 트리의 관계
렌더러는 DOM 요소에 부합하지만 1:1 대응관계는 아닌다. 예를 들어 "head" 요소와 같은 비시각적 DOM 요소는 렌더 트리에 추가되지 않는다. 또한 display: none 요소는 트리에 나타나지 않는다.
어떤 렌더 객체는 DOM 노드에 대응하지만 트리와 동일한 위치에 있지 않다. float 처리된 요소 또는 position: absolute 요소는 흐름에서 벗어나 트리의 다른 곳에 배치된 상태로 형상이 그려진다. 대신 자리 표시자가 원래 있어야 할 곳에 배치된다.
트리를 구축하는 과정
html 태그와 body 태그를 처리함으로써 렌더 트리 루트를 구성한다. 루트 렌더 객체는 CSS 명세에서 포함 블록(다른 모든 블록을 포함하는 최상위 블록)이라고 부르는 것과 일치한다. 이것이 Document가 가리키는 랜더 객체이다. 트리의 나머지 부분은 DOM 노드를 추가함으로써 구축된다.
4. 렌더 트리 레이아웃(배치)
렌더 트리는 위치와 크기를 가지고 있지 않기 때문에, 어느 공간에 위치해야 할지 각 객체들에게 위치와 크기를 결정해준다.
5. 렌더 트리 페인팅(그리기)
랜더 트리가 만들어져 레이아웃이 구성되었으면 UI 백엔드가 동작하여 렌더 트리의 각 객체를 화면의 픽셀(px)값으로 나타낸다.
JavaScript 렌더링
자바스크립트 렌더링은 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.
HTML 파서는 script 태그를 만나면 자바스크립트 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 제어 권한을 넘긴다.
제어 권한을 넘겨 받은 자바스크립트 엔진은 script 태그 내의 자바스크립트 코드 또는 script 태그의 src attribute에 정의된 자바스크립트 파일을 로드하고 파싱하여 실행한다.
자바스크립트의 실행이 완료되면 다시 HTML 파서로 제어 권한을 넘겨서 브라우저가 중지했던 시점부터 DOM 생성을 재개한다.
이처럼 브라우저는 동기적(Synchronous)적으로 HTML, CSS, Javascript를 처리한다. 이것은 script 태그의 위치에 따라 블로킹이 발생하여 DOM의 생성이 지연될 수 있다는 것을 의미한다. 따라서 script 태그의 위치는 중요한 의미를 갖는다.
body 요소의 가장 아래에 자바스크립트를 위치시키는 것은 좋은 아이디어다. 그 이유는 아래와 같다.
- HTML 요소들이 스크립트 로딩 지연으로 인해 랜더링에 지장 받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다.
- DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작한다면 에러가 발생한다.
Reference
'BackEnd' 카테고리의 다른 글
모노리틱 아키텍처(Monolithic Architecture) vs 마이크로 서비스 아키텍처(Micro Service Architecture) (0) | 2022.02.07 |
---|---|
REST API 설계 가이드 (0) | 2022.01.13 |
Data Warehouse Vs Data Lake (2) | 2021.10.12 |
댓글