게시일: 2014년 3월 31일
브라우저가 페이지를 렌더링하려면 먼저 DOM과 CSSOM 트리. 따라서 HTML과 모바일 애플리케이션 CSS를 브라우저에 최대한 빠르게 전달합니다.
요약
- 바이트 → 문자 → 토큰 → 노드 → 객체 모델.
- HTML 마크업이 DOM (Document Object Model)으로 변환됩니다. CSS 마크업은 CSSOM (CSS Object Model)으로 변환됩니다.
- DOM 및 CSSOM은 독립적인 데이터 구조입니다.
- Chrome DevTools Performance 패널을 사용하면 구성을 캡처하고 검사할 수 있습니다. DOM 및 CSSOM의 처리 비용입니다.
문서 객체 모델 (DOM)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
가장 단순한 경우인 몇몇 텍스트와 하나의 이미지만 포함하는 일반 HTML 페이지부터 살펴보도록 하겠습니다. 브라우저가 이 페이지를 어떻게 처리하나요?
- 변환: 브라우저가 디스크나 네트워크에서 HTML의 원시 바이트를 읽어와서, 해당 파일에 대해 지정된 인코딩(예: UTF-8)에 따라 개별 문자로 변환합니다.
- 토큰화: 브라우저가 문자열을 고유한 문자열로 변환합니다.
W3C HTML5 표준
예를 들어
<html>
,<body>
과 꺾쇠 괄호로 묶여 있습니다. 각 토큰에는 특별한 의미와 고유한 규칙 세트가 있습니다. - 렉싱: 방출된 토큰은 해당 속성 및 규칙을 정의하는 '객체'로 변환됩니다.
- DOM 구성: 마지막으로, HTML 마크업이 서로 다른 태그 간의 관계를 정의하므로(일부 태그는 다른 태그 내에 포함됨) 생성된 객체는 원래 마크업에 정의된 상위-하위 관계도 캡처하는 트리 데이터 구조로 연결됩니다. 문서의 전체 표현이 빌드될 때까지 HTML 객체는 body 객체의 상위 요소이고 body는 paragraph 객체의 상위 요소입니다.
이 전체 프로세스의 최종 출력이 바로 이 간단한 페이지의 DOM(Document Object Model)이며, 브라우저는 이후 모든 페이지 처리에 이 DOM을 사용합니다.
브라우저는 HTML 마크업을 처리할 때마다 이전에 정의된 모든 단계를 거칩니다. 즉, 바이트를 문자로 변환하고, 토큰을 식별한 후 노드로 변환하고 DOM 트리를 빌드합니다. 이 전체 프로세스를 완료하려면 시간이 약간 걸릴 수 있으며, 특히 처리해야 할 HTML이 많은 경우 그렇습니다.
Chrome DevTools를 열고 페이지가 로드되는 동안 타임라인을 기록하면 이 단계를 수행하는 데 소요된 실제 시간을 확인할 수 있습니다. 이전 예시에서는 HTML 조각을 DOM 트리로 변환하는 데 약 5ms 정도 걸렸습니다. 큰 페이지의 경우 이 프로세스가 훨씬 더 오래 걸릴 수 있습니다. 생성 시 매끄러운 애니메이션을 제공할 경우 브라우저에서 대량의 HTML을 처리합니다.
DOM 트리는 문서 마크업의 속성 및 관계를 포함하지만 요소가 렌더링될 때 어떻게 표시될지에 대해서는 알려주지 않습니다. 이는 CSSOM의 책임입니다.
CSS Object Model(CSSOM)
브라우저가 기본 페이지의 DOM을 구성하는 동안
외부 CSS를 참조하는 문서의 <head>
에 있는 <link>
요소
스타일 시트: style.css
페이지를 렌더링하는 데 이 리소스가 필요할 것이라고 판단한 브라우저는 이 리소스에 대한 요청을 즉시 발송하고 요청의 결과로 다음 콘텐츠가 반환됩니다.
body {
font-size: 16px;
}
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
HTML 마크업 내에서 직접 스타일을 선언할 수도 있었지만 (인라인) CSS를 HTML과 독립적으로 유지하면 콘텐츠와 디자인을 따로 신경 쓸 필요가 없습니다. 디자이너는 CSS로 작업할 수 있고, 개발자는 HTML에 집중할 수 있습니다. 다른 문제가 있을 수 있습니다
HTML과 마찬가지로, 수신된 CSS 규칙을 브라우저가 이해하고 처리할 수 있는 형식으로 변환해야 합니다. 따라서 HTML 프로세스를 반복합니다. HTML 대신 CSS의 경우:
CSS 바이트가 문자로 변환된 후 차례로 토큰과 노드로 변환되고 마지막으로 'CSS Object Model'(CSSOM)이라는 트리 구조에 링크됩니다.
CSSOM이 트리 구조인 이유는 무엇인가요? 페이지의 객체에 대한 최종 스타일 집합을 계산할 때 브라우저는 해당 노드에 적용할 수 있는 가장 일반적인 규칙으로 시작합니다(예: 본문 요소의 하위 요소인 경우 모든 본문 스타일이 적용됨). 그런 다음 더 구체적인 규칙을 적용하여 계산된 스타일을 재귀적으로 미세 조정합니다. 즉, 규칙이 '하위로 캐스케이드'됩니다.
더욱 구체화하기 위해 앞에서 설명한 CSSOM 트리를 살펴봅시다. 모든 텍스트
본문 요소 내에 있는 <span>
태그 내에 포함되어 있으며
글꼴 크기는 16픽셀이며 빨간색 텍스트가 있음: font-size
지시어가 계단식으로 표시됨
body
에서 span
로 내려갑니다. 그러나 span
이
단락 (p
) 태그가 포함된 경우 콘텐츠가 표시되지 않습니다.
또한 앞에서 설명한 트리는 완전한 CSSOM 트리가 아니고 스타일시트에서 재정의하도록 결정한 스타일만 표시한다는 점에 유의하세요. 모든 브라우저는 '사용자 에이전트 스타일'이라고 하는 기본 스타일 집합을 제공합니다. 이는 개발자가 자체 스타일을 제공하지 않을 때 표시되는 스타일입니다. 개발자가 작성하는 스타일은 이러한 기본 스타일을 재정의합니다.
CSS 처리에 걸리는 시간을 확인하려면 DevTools에서 타임라인을 기록하고 'Recalculate Style' 이벤트를 찾습니다. DOM 파싱과 달리 타임라인에는 별도의 'Parse CSS' 항목이 표시되지 않으며 대신 파싱 및 CSSOM 트리 생성과 계산된 스타일의 재귀적 계산이 이 단일 이벤트에서 캡처됩니다.
이 사소한 스타일 시트는 처리하는 데 약 0.6ms가 걸리고 많지는 않지만 다시 한번 무료는 아닙니다. 그런데 8개 요소는 어디서 왔을까요? CSSOM 및 DOM은 서로 독립적인 데이터 구조입니다. 알고보니 브라우저에서 숨겨진 중요한 단계가 있습니다. 다음으로 렌더링 트리가 DOM과 CSSOM을 함께 연결합니다.