"Mark" 또는 "Tag"로 감싸진 언어이다. 예로 HTML, XML 등 있다.
Document Type Definition 라고도 하며, 사용할 HTML의 버전을 명시하여, 인터넷 브라우저에 알려 준다.
호환 모드(quirks mode)
기존 방식으로 제작된 웹사이트들을 표현하기 위해 Navigator 4와 IE5의 비표준 동작들을 에뮬레이션
완전 표준 모드(full standards mode; 이하 표준 모드)에서는 HTML과 CSS에 의해 웹 페이지가 표시
거의 표준 모드(almost standards mode)는 소수의 호환 모드 요소만 지원
HTML은 Markup Language 의 Hyper Text 이다. 간단히 말해서 HTML은 웹 브라우저에 웹 사이트의 특정 부분을 표시하는 방법을 알려주는 명령 집합이다.
<h1>Header</h1>
<p>
Paragraph
<a href=”…”>Hyperlink</a>
.
</p>
<ul>
<li>List</li>
<li>List</li>
</ul>
꺾쇠 괄호 <> 안에있는 부분을 태그라고 한다. 태그는 해당 텍스트를 특정 방식으로 표시해야 함을 브라우저에게 알리는 명령이다. 또한 태그는 특정 위치에 이미지 또는 버튼 등이 있어야 함을 브라우저에 알린다.
이러한 태그를 텍스트 파일에 넣고 브라우저에 표시한다.
브라우저는 태그를 읽고, 태그없이 웹 페이지를 렌더링하지만 태그 의미를 염두한다.
Header
Paragraph hyperlink.
● List
● List2
<head>…</head>
— 직접 렌더링되지 않지만, 페이지가 작동하는 방식에 영향을 미치는 페이지의 서비스 영역
<title>…</title>
— <head>
안에 포함되며, 이 태그 안의 텍스트는 탭 표시 줄과 즐겨 찾기에 표시
<body>…</body>
— 페이지의 보이는 부분
<h1>…</h1>
, <h2>…</h2>
등등 — 다른 수준의 헤더
<p>… </ p>
— 텍스트 단락
<a href=”…”>…</a>
— 하이퍼링크
<img src=”…”>
— 이미지
<ul><li>…</li></ul>
— 순서 없는 목록
<ol><li>…</li></ol>
— 수로 정렬된 목록
<div>…</div>
— 페이지 내부의 범용 블록
<span>…</span>
— 원하는 모양으로 커스터마이징 할 수 있는 텍스트의 일부
<table><tbody><tr><td>…</td><td>…</td></tr></tbody></table>
— 최소한의 테이블을 렌더링하기 위한 태그 세트
<tbody>
— '테이블 body'
<th>
— '테이블 header'
<tr>
— '테이블 행'
<td>
— '테이블 분할'또는 '테이블 셀'
브라우저가 HTML 코드를 읽을 때, HTML element를 만날 때마다 Node라는 JavaScript 객체를 생성한다. 결국 모든 HTML element는 JavaScript 객체로 변환된다. HTML element 마다 속성이 다르기 때문에 Node 객체는 각기 다른 클래스(생성자 함수)에서 생성된다.
예를 들어 div 요소에 대한 Node 객체는 Node 클래스를 상속하는 HTML Div Element에서 생성된다.
브라우저에는 HTMLDivElement, HTMLScriptElement, Node 등과 같은 기본 제공 클래스가 있다.
브라우저가 HTML 문서에서 Node를 만든 후에는, 이러한 Node 객체 트리와 같은 구조를 만들어야 한다. HTML element가 서로 중첩되므로, 브라우저는 이를 복제해야 하지만 이전에 만든 Node 객체를 사용한다. 이렇게하면 브라우저가 수명주기 동안 웹 페이지를 효율적으로 렌더링하고 관리할 수 있다.
HTML 문서의 DOM 트리는 위와 같다. DOM 트리는 html element 최상위 요소에서 시작하여, element 발생 및 중첩에 따라 분기된다. HTML element가 발견 될 때마다 해당 클래스(생성자 함수)에서 DOM Node 객체를 만든다.
DOM Node가 항상 HTML 요소일 필요는 없다. 브라우저가 DOM 트리를 생성 할 때 주석, 속성, 텍스트와 같은 것들도 트리에 별도 Node로 저장한다.
아래와 같이 Google Chrome DevTools Console에서 DOM 트리를 시각화 할 수 있다. 그러면 각 DOM element의 속성과 함께 DOM element의 계층(DOM 트리의 상위 수준보기)이 표시된다.
Javascript는 DOM이 무엇인지 이해하지 못하며, Javascript 사양의 일부가 아니다. DOM은 웹 페이지를 효율적으로 렌더링하고, 개발자가 다양한 목적을 위해 DOM 요소를 동적으로 조작 할 수 있도록 공개적으로 노출하기 위해 브라우저에서 제공하는 고급 웹 API이다.
개발자는 DOM API를 사용하여 HTML element를 추가/제거하고, 모양 변경 및 이벤트 리스너 바인딩이 가능하다. DOM API를 사용하면 렌더링된 DOM 트리에 영향을 주지 않고 HTML element를 메모리에서 생성하거나 복제하고 관리 할 수 있다.
CSS selector를 사용하여 DOM element를 대상으로 색상, 글꼴, 크기와 같은 style 속성을 설정할 수 있다.
외부 CSS 파일,<style>
태그, HTML element의 inline style 사용 또는 JavaScript 사용과 같은 다양한 방법이 있다. 그러나 결국 브라우저는 CSS를 DOM element에 적용하는 무거운 작업을 수행해야한다.
html {
padding: 0;
margin: 0;
}
body {
font-size: 14px;
}
.container {
width: 300px;
height: 200px;
color: black;
}
.container > h1 {
color: gray;
}
.container > p {
font-size: 12px;
display: none;
}
DOM을 구성한 후 브라우저는 모든 소스 (external, embedded, inline, user agent 등)에서 CSS를 읽고 CSSOM을 구성한다. CSSOM은 DOM과 같은 Tree 구조 이다.
이 트리의 각 Node에는 특정 DOM element에 대한 CSS 스타일 정보가 포함되어 있다. 그러나 CSSOM에는<meta>
,<script>
,<title>
등과 같이 화면에 인쇄 할 수없는 DOM 요소가 포함되어 있지 않다.
대부분 브라우저는 user agent stylesheet라고 하는 자체 stylesheet로 재정의하여 (특수성 규칙 사용), 최종 CSS 속성을 계산한 다음 Node를 구성한다.
특정 HTML element에 대한 CSS 속성이 정의되지 않은 경우에도, W3C CSS 표준에 지정된대로 해당 속성의 기본값으로 설정된다.
Render-Tree는 DOM과 CSSOM 트리를 결합하여 구성된 트리 구조이다. 브라우저는 Render-Tree를 사용하기 때문에 각 보이는 요소의 레이아웃을 계산하고 화면에 페인트가 가능하다. 따라서 Render-Tree가 구성되지 않으면 화면에 아무것도 인쇄되지 않는다.
Render-Tree는 궁극적으로 화면에 그려질 항목의 low-level 표현이므로 pixel matrix의 영역이 없는 Node는 제외한다. 예를 들어, display : none 요소의 크기는 0px X 0px이므로 Render-Tree에 표시되지 않는다.
위의 다이어그램에서 볼 수 있듯, Render-Tree는 DOM과 CSSOM을 결합하여 화면에 인쇄 될 요소만 포함하는 트리형 구조를 생성한다.
브라우저에 의해 구성된 DOM 트리의 DOM element에 대한 액세스를 제공하는 DOM API와 달리 CSSOM은 사용자에게 숨겨져 있다. 그러나 브라우저는 DOM과 CSSOM을 결합하여 렌더 트리를 형성하므로 브라우저는 DOM element 자체에 고급 API를 제공하여 DOM element의 CSSOM 노드를 노출한다. 이를 통해 개발자는 CSSOM 노드의 CSS 속성에 액세스하거나 변경할 수 있다.
웹 페이지가 로드되면 브라우저는 먼저 TEXT HTML을 읽고 여기에서 DOM 트리를 구성한다. 그런 다음 CSS를 처리하고 여기에서 CSSOM 트리를 구성한니다. 이러한 트리가 생성 된 후에는 여기에서 Render-Tree를 생성한니다. Render-Tree가 생성되면 브라우저는 화면에 개별 element를 인쇄하기 시작한다.
첫 번째 브라우저는 각 개별 Render-Tree Node의 레이아웃을 만든다. 레이아웃은 각 Node의 크기(px)와 화면에서 인쇄 될 위치(position)로 구성된다.
이 프로세스는 reflow 또는 browser reflow라고도 하며, 스크롤, window 크기 조정 등 DOM 요소를 조작 할 때도 발생한다. (관련 문서)
이제 레이어가 생겼으므로 이를 결합하여 화면에 그릴 수 있다. 그러나 브라우저는 단일 이미지에 모든 레이어를 그리지 않는다. 각 레이어가 먼저 별도로 그려진다.
각 레이어 내에서 브라우저는 테두리, 배경색, 그림자, 텍스트 등과 같은 요소의 가시적 속성으로 개별 픽셀을 채운다. 이 프로세스를 래스터화(rasterization)라고도 한다. 성능을 향상시키기 위해, 브라우저는 다른 스레드를 사용하여 래스터화를 수행 할 수 있다.
합성 작업에서 reflow, 래스터화한 레이어는 GPU로 전송되어 최종적으로 화면에 그려진다.
화면을 그려야 할때마다 전체 레이어를 보내는 것은 reflow 및 래스터화를 재반복 해야 하기에 비효율적이다. 때문에 레이어를 여러 타일로 분할해야 한다.
이와 같은 일련의 이벤트를 중요 렌더링 경로(Critical rendering path)라고도 한다.
일반적인 웹 페이지에는 HTML, JavaScript 및 CSS가 포함됩니다. 브라우저는 HTML을 위에서 아래로 구문 분석하여 DOM을 구성한다. 포함 된 JavaScript 및 CSS 가있는 경우 동기적으로 구문 분석 한다.
외부 JavaScript 파일을 로드하는<script src = "">
의 경우, 브라우저가 외부 JavaScript를 만날 때마다 JavaScript 파일이 다운로드되고 구문 분석 될 때까지 DOM 구성이 중지된다.
반면 브라우저가 외부 CSS를 로드하는 데 사용되는<link rel="stylesheet">
를 발견하면 .css 파일을 비동기적으로 가져오라는 요청을 보내고, 아래 다른 HTML element를 파싱하기 위해 다시 이동한다.
DOM과 CSSOM이 모두 생성되고 Render-Tree가 생성 되려고 할 때 DOMContentLoaded가 실행된다.
DOMContentLoaded 이벤트는 window.onload 이벤트와 다르다. DOMContentLoaded 이벤트는 모든 외부 자바 스크립트가 파싱된 후 DOM이 완전히 준비된 지점을 표시한다. 반면 window.onload 이벤트의 경우, 외부 스타일 시트와 파일이 다운로드되고 웹 페이지가 완전히 준비된 지점을 표시한다.
여기서 주의할 점은 CSS는 렌더링 차단 리소스이다. 즉, 외부 CSS가 다운로드되고 구문 분석 될 때까지 브라우저는 렌더링을 멈춘다. CSSOM 생성이 차단됨에 따라 브라우저에서 DOMContentLoaded 이벤트가 시작되지 않는다. 따라서 외부 스타일 시트는 비동기적으로 로드 되지만, 동기적으로 구문 분석 된다.
async 는 load-first order, 즉 문서 내 순서와 상관없이 먼저 다운로드된 스크립트가 우선 실행된다. 반면 defer 는 문서에 추가된 순서로 실행된다.
async는 HTML 문서가 완전히 다운로드되지 않은 상태라도 로드 및 실행될 수 있다. 스크립트 크기가 작거나 캐싱 처리 되어있을 때, 혹은 HTML 문서 길이가 아주 길 때 이런 일이 발생한다. defer 는 문서 다운로드와 파싱이 완료된 후에, DOMContentLoaded 이벤트 발생 전에 실행된다.
async는 방문자 수 카운터나 광고관련 스크립트같이 독립적인 스크립트에 혹은 실행 순서가 중요하지 않은 경우에 적용한다. 실무에선 defer를 DOM 전체가 필요한 스크립트나 실행 순서가 중요한 경우에 적용한다.
DOM 트리, CSSOM 트리 및 핸들 렌더링 논리를 만드는 작업은 렌더링 엔진 또는 레이아웃 엔진이라고도하는 브라우저 엔진이라는 소프트웨어를 사용하여 수행된다. 이러한 브라우저 엔진에는 HTML 파일의 웹 페이지를 화면의 실제 픽셀로 렌더링하는데 필요한 모든 element와 논리가 포함되어 있다.
IE
Engine: Trident
CSS-prefix: -ms
Edge
Engine: EdgeHTML → Blink
CSS-prefix: -ms
Firefox
Engine: Gecko
CSS-prefix: -moz
Opera
Engine: Presto → Blink
CSS-prefix: -o (Presto) and -webkit (Blink)
Safari
Engine: WebKit
CSS-prefix: -webkit
Chrome
Engine: WebKit → Blink
CSS-prefix: -webkit