면접질문 CRP

Critical Rendering Path

일단 일반적인 CRP 과정부터 이야기 해보자.

CRP에 대해 이야기 하기전에 개념부터 잡자

1. CRP 개념 잡기

1-1. DOM

DOM (DOCUMENT OBJECT MODEL)은 문서객체모델 트리는 완전히 구분 분석된 HTML 페이지를 의미한다.
쉽게 우리는 개발자도구를 통해 DOM을 볼수 있다. 이 DOM은 HTML이 브라우저의 렌더링 엔진에의해 파싱되면서 구문을 위에서 아래로 분석하는데 이 구문 분석이 모두 끝나고 HTML파일이 DOM이다. DOM이 CSSOM과 다른점은 부분적으로 문서를 로드할 수 있다는 점.

1-2. CSSOM

CSS (CSS OBJECT MODEL)은 DOM과 관련된 스타일의 객체표현. CSS는 렌더링 차단 리소스로 간주되서 이 CSS리소스가 완전히 구문분석되지 않고는 렌더 트리를 구성할 수 없다. 즉 DOM과 달리 완전히 CSSOM이 만들어질때까지 렌더트리에 포함되지 않는다.

단 orientation:lanscape 같은 속성이 있는 스타일의 경우 해당 속성일 경우만 적용되기 때문에 이런경우는 렌더링 차단으로 간주되지 않는다. 즉 현재장치에 적용되는 경우에만 렌더링 차단으로 간주됨.

또한 CSS는 스크립트차단 리소스가 될 수 있다. 왜냐하면 렌더링 엔진이 자바스크립트가 실행되는 구문에 도달하게되면 렌더링엔진은 자바스크립트 런타입엔진에 역할을 내어준다. 왜냐하면 브라우저는 싱글쓰레드이기 때문에 자바스크립트파일을 다운받고 실행이 되기전까지 DOM, CSSOM은 진행되지 않는다. 따라서 자바스크립트소스는 가장 마지막에 참조되는 것이 좋다 어차피 자바스크립트가 dom을 조작하려고 하는경우라면, dom과 cssom이 없으면 제대로 동작하지 않기에...

하지만 dom조작을 하지 않는 스크립트의 경우 가장 상단에 오는 경우가 있을 수 있지만 알다시피 이 스크립트 부분에 구문분석이 되면 다운로드 및 실행전까지 렌더링엔진은 동작을 하지 않는다.

1-3. javascript

자바스크립트는 파서차단 리소스 이다. 즉 HTML문서 자체의 구분분석이 javascript에 의해 차단되기 때문이다. 파서가 태그에 도달하면 실행을 중단한다. 하지만 만약 이를 async속성을 적용하면 비동기적로드를 할수있다.

<script async src="script.js">

2. CRP 과정

그림을 보면 알겠지만 서버로부터 html을 받아오면 렌더링엔진으로부터 DOM이 빌드되는데 구분분석이 시작되면서 CSS, JS와 관련된 구문을 만나면 DOM렌더링은 각각의 실행이 끝날때까지 중단되고 이후 DOM빌드를 마무리한다.

아래 과정은 링크에서 발췌한 내용입니다. 엄청 정리가 잘 되어 있습니다.

렌더트리는 DOM과 CSSOM의 조합이다. 페이지에서 최종적으로 렌더링될 내용을 나타내는 트리인데. 보이는 부분만 적용되고 display:none과 같이 보이지 않는 부분은 포함되지 않는다.

2-1. DOM 생성

  1. 브라우저는 html의 원시바이트를 해당파일에 지정된 인코딩에 따라 개별 문자로 변환한다.
  2. 브라우저가 문자열을 w3c html5 표준에 지정된 고유 토큰으로 변환된다.
  3. 이 토큰들은 노드객체로 변환된다.
  4. 이 노드 객체들은 DOM트리로 생성된다.

2-2. CSSOM 생성

DOM과 동일한 과정을 통해 CSSOM이 변환된다.

2-3. 렌더트리

이렇게 생성된 DOM과 CSSOM이 만나서 렌더트리가 만들어진다. 즉 렌더트리는 화면에 표시되는 모든 노드의 콘첸츠 및 스타일 정보를 모두 포함한다.

이렇게 렌더트리가 마무리 된 과정까지를 construction 파트 이후 단계를 operation 파트로 구분한다.

2-4. Layout(Reflow)

렌더트리에는 노드와 노드의 스타일만 계산되어 있다. Layout에서는 화면에 표시될 노드의 정확한 위치와 크기를 게산한다.

2-5. Paint, Rasterize, Composite Layer (Repaint)


이후 다음 과정을 통해 화면포출이 완료된다.

3. 시각적 요인 변경

사용자의 화면이 변경될때 다음 3가지 단계가 있을 수 있다.

3-1. 만약 레이아웃(width, height, left, top 등 layout속성)에 영향을 주는 스타일 속성이 변한다면

화면은 리플로우(가장 안좋은..)를 수행한다. 즉 렌더트리 생성이후 단계를 반복한다는 의미이다.

js > style > layout > paint > composition

3-2. 레이아웃에 영향을 주지 않는 배경이미지, 텍스트 색상 그림자 등 paint속성만 변경한다면

화면은 layout을 건너띄고 아래와 같이 동작한다.

js > style > paint > composition

3-3. 레이아웃과 페인트 속성의 변경이 없다면

화면은 layout, paint단계를 건너띄고 다음과 같이 동작한다.

js > style > composition

4. 네비게이션 타이밍

Navigation Timing API는 웹사이트의 성능을 측정하는데 사용할 수 있는 데이터르 제공한다.

// 로딩시간 측정법
function onLoad() {
  var now = new Date().getTime();
  var page_load_time = now - performance.timing.navigationStart;
  console.log("User-perceived page loading time: " + page_load_time);
}
// 어떤 페이지를 로딩하는데 필요한 전체 시간 계산하기
var perfData = window.performance.timing;
var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
// 요청 응답 시간 계산하기.
var connectTime = perfData.responseEnd - perfData.requestStart;

  • processing

    • domLoading
      브라우저가 처음 수신한 HTML 문서 바이트의 파싱을 시작하려고 하는 상태입니다.
    • domInteractive
      브라우저가 파싱을 완료한 시점 즉, DOM이 준비된 상태입니다.
      파서 차단 자바스크립트가 없으면 domInteractive 직후에 DOMContentLoaded 이벤트가 발생할 것입니다.
    • domContentLoaded
      DOM이 준비되고 자바스크립트 실행을 차단하는 스타일시트가 없는 상태입니다. 즉, DOM 및 CSSOM이 모두 준비된 상태로 렌더링 트리를 생성할 수 있습니다.
      많은 자바스크립트 프레임워크가 자체 로직을 실행하기 전에 이 이벤트를 기다립니다.
    • domComplete
      페이지 및 해당 하위의 모든 리소스가 준비된 상태입니다.
      이름이 의미하는 바와 같이, 모든 처리가 완료되고 페이지의 모든 리소스(이미지 등) 다운로드가 완료되었습니다( 예: 로딩 스피너가 회전을 멈춤).
  • Load

    • loadEvent
      각 페이지 로드의 최종 단계로, 브라우저가 추가 애플리케이션 로직을 트리거할 수 있는 상태로 onload 이벤트를 발생시킵니다.

참고링크

좋은 웹페이지 즐겨찾기