
각 구성 요소는 다음과 같은 역할을 하고 있다. 물론 구조는 브라우저마다 조금씩 다를 수 있다.
크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지하는 것이 주목할만하다. 각 탭은 독립된 프로세스로 처리된다.
렌더링 엔진은 요청받은 내용을 브라우저 화면에 표시해주는 역할을 한다. 브라우저마다 사용하는 렌더링 엔진이 각각 다르기 때문에, 모든 브라우저가 동일한 소스를 화면에 동일하게 그려주지 않고 엔진마다 읽을 수 있는 코드의 버전도 다르기 때문에 크로스 브라우징 이슈가 발생하곤 한다.
| 브라우저 | 렌더링 엔진 |
|---|---|
| IE | Trident |
| Edge | EdgeHTML, Blink |
| Chrome | Webkit, Blink(버전 28 이후) |
| Safari | Webkit |
| FireFox | Gecko |
파이어폭스는 게코(Gecko), 사파리는 웹킷(Webkit), 크롬의 경우 웹킷을 사용하다가 웹킷을 Fork하여 블링크 엔진을 자체적으로 구현하여 사용한다. 각각의 렌더링 엔진들은 웹 표준에 따라서 개발자들이 작성한 문서를 브라우저에 보여주지만, 개발 진척도나 별도 규칙에 따라 지원하는 표준이 다르거나 렌더링 알고리즘과 방식에 차이가 있을 수 있다.
렌더링 엔진은 서버로부터 응답받은 HTML 문서를 얻는 것으로 시작합니다. 이 문서의 내용은 보통 8KB 단위로 전송됩니다.
![]()
① 렌더링 엔진은 HTML 문서를 파싱 하여 DOM 트리를 구축합니다.
② 그다음 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱 합니다.
③ DOM 트리와 ②의 결과물을 합쳐 렌더 트리를 구축합니다.
④ 렌더 트리 각 노드에 대해 화면 상에서 배치할 곳을 결정합니다.
⑤ UI 백엔드에서 렌더 트리의 각 노드를 그립니다.
![]()
① HTML 문서를 파싱 하여 DOM(Document Object Model) 트리를 구축
DOM은 마크업과 1:1 관계를 성립
<html>
<body>
<p>Hello World</p>
<div><img src="example.png" /></div>
</body>
</html>
위와 같은 코드는 아래와 같은 DOM 트리로 변환할 수 있다.
![]()
② CSSOM(Css Object Model)을 생성
![]()
③ 렌더 트리(DOM + CSSOM)를 생성
DOM 트리가 구축되는 동안 브라우저는 DOM 트리를 기반으로 렌더 트리를 생성
렌더 트리는 문서를 시각적인 구성 요소로 만들어주는 역할을 한다.
웹킷은 이 구성 요소를 "렌더러(rendere)" 또는 "렌더 객체(render object)"라는 용어를 사용한다. 렌더러는 자신과 자식 요소를 어떻게 배치하고 그려내야 하는지 알고 있다.
렌더러는 DOM 요소에 부합하지만 1:1로 대응하는 관계는 아니다. 그 이유는 <head>, display:'none'와 같은 사용자가 볼 수 없는 DOM 요소는 렌더 트리에 추가되지 않는다. (visibility 속성에 "hidden" 값이 할당된 요소는 트리에 나타난다.)
![]()
④ 렌더 트리를 배치 (레이아웃)
렌더 트리는 위치와 크기를 가지고 있지 않기 때문에, 어느 공간에 위치해야 할지 각 객체들에게 위치(position)와 크기(size)를 결정해줍니다.
⑤ 렌더 트리를 그린다
렌더 트리가 만들어져 레이아웃이 구성되었으면 UI 백엔드가 동작하여 렌더 트리의 각 객체를 화면의 픽셀(px) 값으로 나타냅니다.
자바스크립트는 자바스크립트 엔진이 처리
HTML 파서는 <script> 태그를 만나면 Javascript 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 권한을 넘깁니다. 제어 권한을 넘겨받은 자바스크립트 엔진은 <script> 태그 내의 Javascript 코드 또는 src 속성에 정의된 Javascript 파일을 로드하고 파싱 하여 실행합니다. Javascript의 실행이 완료되면 다시 HTML 파서로 제어 권한을 넘겨서 중지했던 시점으로 돌아가 DOM 생성을 재개합니다.
![]()
이처럼 브라우저는 동기적으로 HTML, CSS, Javascript를 처리합니다. 하지만 자바스크립트 엔진에 제어 권한이 있을 때 Javascript 코드가 완성되지 않은 DOM을 조작하게 된다면 어떻게 될까요? 당연히 에러가 발생할 것입니다.
이것이 HTML 파일에서 Javascript 코드를 태그 하단에 위치시키는 이유입니다.