객체 모델 구성

Ilya Grigorik
Ilya Grigorik

게시일: 2014년 3월 31일

브라우저가 페이지를 렌더링하려면 먼저 DOM 및 CSSOM 트리를 구성해야 합니다. 따라서 HTML과 CSS를 모두 브라우저에 최대한 빨리 전송해야 합니다.

  • 바이트 → 문자 → 토큰 → 노드 → 객체 모델
  • HTML 마크업은 문서 객체 모델 (DOM)로 변환되고 CSS 마크업은 CSS 객체 모델 (CSSOM)로 변환됩니다.
  • DOM과 CSSOM은 독립적인 데이터 구조입니다.
  • Chrome DevTools 성능 패널을 사용하면 DOM 및 CSSOM의 생성 및 처리 비용을 캡처하고 검사할 수 있습니다.
<!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 페이지로 시작합니다. 브라우저는 이 페이지를 어떻게 처리하나요?

DOM 구성 프로세스

  1. 변환: 브라우저는 디스크 또는 네트워크에서 HTML의 원시 바이트를 읽고 지정된 파일 인코딩 (예: UTF-8)에 따라 개별 문자로 변환합니다.
  2. 토큰화: 브라우저는 문자열을 W3C HTML5 표준에 따라 구체적으로 지정된 것과 같이 고유한 토큰(예: <html>, <body>) 및 각괄호 내의 다른 문자열로 변환합니다. 각 토큰에는 특별한 의미와 고유한 규칙이 있습니다.
  3. 리싱: 내보낸 토큰은 속성과 규칙을 정의하는 '객체'로 변환됩니다.
  4. DOM 구성: 마지막으로, HTML 마크업은 서로 다른 태그 간의 관계를 정의하므로 (일부 태그는 다른 태그 내에 포함됨) 생성된 객체는 원래 마크업에 정의된 상위-하위 관계도 캡처하는 트리 데이터 구조로 연결됩니다. 문서의 전체 표현이 빌드될 때까지 HTML 객체는 body 객체의 상위 요소이고 bodyparagraph 객체의 상위 요소입니다.

DOM 트리

이 전체 프로세스의 최종 출력은 간단한 페이지의 문서 객체 모델 (DOM)이며, 브라우저는 페이지의 모든 추가 처리에 이를 사용합니다.

브라우저가 HTML 마크업을 처리할 때마다 이전에 정의된 모든 단계(바이트를 문자로 변환, 토큰 식별, 토큰을 노드로 변환, DOM 트리 빌드)를 거칩니다. 이 전체 프로세스는 특히 처리할 HTML이 많은 경우 시간이 다소 걸릴 수 있습니다.

DevTools에서 DOM 생성 추적

Chrome DevTools를 열고 페이지가 로드되는 동안 타임라인을 기록하면 이 단계를 실행하는 데 걸린 실제 시간을 확인할 수 있습니다. 이전 예에서는 HTML 청크를 DOM 트리로 변환하는 데 약 5ms가 걸렸습니다. 페이지가 더 크면 이 프로세스에 훨씬 더 오래 걸릴 수 있습니다. 부드러운 애니메이션을 만들 때 브라우저가 대량의 HTML을 처리해야 하는 경우 병목 현상이 발생할 수 있습니다.

DOM 트리는 문서 마크업의 속성과 관계를 캡처하지만 렌더링될 때 요소가 어떻게 표시되는지는 알려주지 않습니다. 이는 CSSOM의 책임입니다.

CSS 객체 모델 (CSSOM)

브라우저가 기본 페이지의 DOM을 구성하는 동안 문서의 <head>에서 외부 CSS 스타일 시트 style.css를 참조하는 <link> 요소가 발견되었습니다. 페이지를 렌더링하는 데 이 리소스가 필요할 것으로 예상하여 즉시 이 리소스에 대한 요청을 전달하고 다음 콘텐츠와 함께 다시 돌아옵니다.

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를 사용합니다.

CSSOM 구성 단계

CSS 바이트는 문자로 변환된 후 토큰으로 변환되고 노드로 변환된 후 'CSS 객체 모델'(CSSOM)이라는 트리 구조에 연결됩니다.

CSSOM 트리

CSSOM에 트리 구조가 있는 이유는 무엇인가요? 페이지의 객체에 대한 최종 스타일 집합을 계산할 때 브라우저는 해당 노드에 적용할 수 있는 가장 일반적인 규칙으로 시작합니다 (예: 본문 요소의 하위 요소인 경우 모든 본문 스타일이 적용됨). 그런 다음 더 구체적인 규칙을 적용하여 계산된 스타일을 재귀적으로 미세 조정합니다. 즉, 규칙이 '하위로 캐스케이드'됩니다.

이를 더 구체적으로 설명하려면 앞에서 설명한 CSSOM 트리를 생각해 보세요. body 요소 내에 배치된 <span> 태그 내에 포함된 모든 텍스트는 글꼴 크기가 16픽셀이고 빨간색 텍스트입니다. font-size 디렉티브는 body에서 span로 아래로 계단식 적용됩니다. 하지만 span가 단락 (p) 태그의 하위 요소인 경우 콘텐츠가 표시되지 않습니다.

또한 앞에서 설명한 트리는 전체 CSSOM 트리가 아니며 스타일 시트에서 재정의하기로 결정한 스타일만 표시합니다. 모든 브라우저는 '사용자 에이전트 스타일'이라고도 하는 기본 스타일 세트를 제공합니다. 이는 자체 스타일을 제공하지 않을 때 표시되는 스타일이며, 자체 스타일은 이러한 기본값을 재정의합니다.

CSS 처리에 걸리는 시간을 확인하려면 DevTools에서 타임라인을 기록하고 '스타일 다시 계산' 이벤트를 찾으면 됩니다. DOM 파싱과 달리 타임라인에는 별도의 'CSS 파싱' 항목이 표시되지 않으며 대신 파싱 및 CSSOM 트리 생성, 그리고 이 하나의 이벤트에서 계산된 스타일의 재귀 계산이 캡처됩니다.

DevTools에서 CSSOM 생성 추적

이 사소한 스타일 시트는 처리하는 데 약 0.6ms가 소요되며 페이지의 8개 요소에 영향을 미칩니다. 그리 많지는 않지만 다시 한번 말하지만 무료가 아닙니다. 하지만 8가지 요소는 어디에서 온 걸까요? CSSOM과 DOM은 독립적인 데이터 구조입니다. 브라우저에서 중요한 단계를 숨기고 있는 것으로 확인되었습니다. 다음으로 DOM과 CSSOM을 서로 연결하는 렌더링 트리를 살펴봅니다.

의견