중요한 렌더링 경로는 웹페이지가 브라우저에서 렌더링을 시작할 때까지의 단계를 말합니다. 페이지를 렌더링하려면 브라우저에 HTML 문서 자체와 이 문서를 렌더링하는 데 필요한 모든 중요한 리소스가 필요합니다.
HTML 문서를 브라우저로 가져오는 방법은 이전 일반 HTML 성능 고려사항 모듈에서 다뤘습니다. 하지만 이 모듈에서는 페이지를 렌더링하기 위해 HTML 문서를 다운로드한 후 브라우저가 실행하는 작업을 자세히 살펴봅니다.
프로그레시브 렌더링
웹은 본질적으로 분산되어 있습니다. 사용하기 전에 설치되는 네이티브 애플리케이션과 달리 브라우저는 페이지를 렌더링하는 데 필요한 모든 리소스가 웹사이트에 있다고 가정할 수 없습니다. 따라서 브라우저는 페이지를 점진적으로 렌더링하는 데 매우 능숙합니다. 네이티브 앱에는 일반적으로 설치 단계와 실행 단계가 있습니다. 그러나 웹페이지와 웹 앱의 경우 이러한 두 단계 간의 경계가 훨씬 덜 명확하며 브라우저는 이를 염두에 두고 설계되었습니다.
브라우저에 페이지를 렌더링할 리소스가 있으면 일반적으로 렌더링을 시작합니다. 따라서 렌더링할 시점을 선택해야 합니다. 언제 렌더링하는 것이 너무 이른가요?
브라우저가 CSS 또는 필요한 JavaScript가 포함되기 전에 HTML이 포함된 상태에서 최대한 빨리 렌더링하면 페이지가 일시적으로 손상된 것처럼 보이고 최종 렌더링 시 상당히 변경됩니다. 이는 브라우저에 더 나은 사용자 환경을 제공하는 초기 렌더링에 필요한 이러한 리소스가 더 많이 확보될 때까지 처음에는 빈 화면을 표시하는 것보다 나쁜 환경입니다.
반면에 브라우저가 순차 렌더링을 실행하는 대신 모든 리소스를 사용할 수 있을 때까지 기다리면 사용자는 오랜 시간 기다려야 합니다. 페이지를 훨씬 더 일찍 사용할 수 있었던 경우라면 불필요하게 기다려야 하는 경우가 많습니다.
브라우저는 명백하게 손상된 환경을 표시하지 않기 위해 기다려야 하는 최소 리소스 수를 알아야 합니다. 반면에 브라우저는 사용자에게 콘텐츠를 표시하기 전에 필요 이상으로 기다려서도 안 됩니다. 브라우저가 첫 번째 렌더링을 실행하기 전에 수행하는 단계의 순서를 중요한 렌더링 경로라고 합니다.
중요한 렌더링 경로를 이해하면 초기 페이지 렌더링을 필요 이상으로 차단하지 않아 웹 성능을 개선할 수 있습니다. 하지만 동시에 중요한 렌더링 경로에서 초기 렌더링에 필요한 리소스를 삭제하여 렌더링이 너무 일찍 발생하지 않도록 하는 것도 중요합니다.
(중요한) 렌더링 경로
렌더링 경로에는 다음 단계가 포함됩니다.
- HTML에서 문서 객체 모델 (DOM)을 구성합니다.
- CSS에서 CSS 객체 모델 (CSSOM)을 구성합니다.
- DOM 또는 CSSOM을 변경하는 JavaScript를 적용합니다.
- DOM 및 CSSOM에서 렌더링 트리 구성
- 페이지에서 스타일 및 레이아웃 작업을 실행하여 어떤 요소가 어디에 적합한지 확인합니다.
- 메모리에 있는 요소의 픽셀을 페인트합니다.
- 겹치는 픽셀이 있으면 픽셀을 합성합니다.
- 결과로 나온 모든 픽셀을 화면에 실제로 그립니다.
이러한 모든 단계가 완료된 후에만 사용자에게 화면에 콘텐츠가 표시됩니다.
이 렌더링 프로세스는 여러 번 실행됩니다. 초기 렌더링은 이 프로세스를 호출하지만 페이지 렌더링에 영향을 미치는 리소스가 더 많이 사용 가능해지면 브라우저는 이 프로세스 또는 일부만 다시 실행하여 사용자가 보는 내용을 업데이트합니다. 중요한 렌더링 경로는 이전에 초기 렌더링에 대해 설명된 프로세스에 중점을 두며, 이에 필요한 중요한 리소스에 종속됩니다.
중요한 렌더링 경로에 있는 리소스는 무엇인가요?
브라우저는 초기 렌더링을 완료하기 전에 일부 중요한 리소스가 다운로드될 때까지 기다려야 합니다. 다음과 같은 리소스가 포함되어 있습니다.
- HTML의 일부입니다.
<head>
요소의 렌더링 차단 CSS<head>
요소의 렌더링 차단 JavaScript
중요한 점은 브라우저가 HTML을 스트리밍 방식으로 처리한다는 것입니다. 브라우저가 페이지의 HTML 일부를 가져오면 즉시 처리를 시작합니다. 그러면 브라우저는 페이지의 나머지 HTML을 수신하기 훨씬 전에 렌더링하기로 결정할 수 있으며, 실제로 그렇게 하는 경우가 많습니다.
중요한 점은 초기 렌더링의 경우 브라우저는 일반적으로 다음을 기다리지 않습니다.
- 모든 HTML
- 글꼴
- 이미지
<head>
요소 외부의 렌더링을 차단하지 않는 JavaScript (예: HTML 끝에 배치된<script>
요소)<head>
요소 외부의 렌더링 차단이 아닌 CSS 또는 현재 뷰포트에 적용되지 않는media
속성 값이 있는 CSS
브라우저는 글꼴과 이미지를 후속 페이지 렌더링 중에 채워야 하는 콘텐츠로 간주하는 경우가 많으므로 초기 렌더링을 중단할 필요가 없습니다. 하지만 텍스트가 글꼴을 기다리거나 이미지를 사용할 수 있을 때까지 숨겨져 있는 동안 빈 공간 영역이 초기 렌더링에 남아 있을 수 있습니다. 더 나쁜 경우는 특정 유형의 콘텐츠에 충분한 공간이 예약되지 않은 경우입니다. 특히 HTML에 이미지 크기가 제공되지 않은 경우 나중에 이 콘텐츠가 로드될 때 페이지 레이아웃이 전환될 수 있습니다. 사용자 환경의 이 측면은 누적 레이아웃 변경 (CLS) 측정항목으로 측정됩니다.
<head>
요소는 중요한 렌더링 경로를 처리하는 데 중요합니다. 다음 섹션에서 자세히 다룹니다. <head>
요소의 콘텐츠를 최적화하는 것이 웹 성능의 핵심 요소입니다. 하지만 지금은 중요한 렌더링 경로를 이해하기 위해 <head>
요소에 페이지 및 리소스에 관한 메타데이터가 포함되어 있지만 사용자가 볼 수 있는 실제 콘텐츠는 포함되어 있지 않다는 사실만 알아두면 됩니다. 표시되는 콘텐츠는 <head>
요소 뒤에 오는 <body>
요소 내에 포함됩니다. 브라우저에서 콘텐츠를 렌더링하려면 렌더링할 콘텐츠와 렌더링 방법에 관한 메타데이터가 모두 필요합니다.
그러나 <head>
요소에서 참조하는 모든 리소스가 초기 페이지 렌더링에 꼭 필요한 것은 아니므로 브라우저는 필요한 리소스만 기다립니다. 중요한 렌더링 경로에 있는 리소스를 식별하려면 렌더링 차단 및 파서 차단 CSS 및 JavaScript를 이해해야 합니다.
렌더링 차단 리소스
일부 리소스는 매우 중요하다고 간주되어 브라우저가 이를 처리할 때까지 페이지 렌더링을 일시중지합니다. CSS는 기본적으로 이 카테고리에 속합니다.
브라우저가 CSS를 보게 되면(<style>
요소의 인라인 CSS이든 <link rel=stylesheet href="...">
요소로 지정된 외부 참조 리소스이든) CSS 다운로드 및 처리가 완료될 때까지 더 이상 콘텐츠를 렌더링하지 않습니다.
리소스가 렌더링을 차단한다고 해서 브라우저가 다른 작업을 중지하는 것은 아닙니다. 브라우저는 최대한 효율적으로 작동하려고 하므로 CSS 리소스를 다운로드해야 한다고 판단되면 이를 요청하고 렌더링을 일시중지하지만 나머지 HTML은 계속 처리하고 그동안 할 다른 작업을 찾습니다.
CSS와 같은 렌더링 차단 리소스는 발견 시 페이지의 모든 렌더링을 차단하는 데 사용되었습니다. 즉, 일부 CSS가 렌더링 차단인지 여부는 브라우저에서 이를 감지했는지 여부에 따라 달라집니다. 일부 브라우저 (처음에는 Firefox, 현재는 Chrome도 포함)는 렌더링 차단 리소스 아래의 콘텐츠 렌더링만 차단합니다. 즉, 중요한 렌더링 차단 경로의 경우 일반적으로 <head>
의 렌더링 차단 리소스에 관심이 있습니다. 이러한 리소스는 전체 페이지의 렌더링을 효과적으로 차단하기 때문입니다.
최근의 혁신은 Chrome 105에 추가된 blocking=render
속성입니다. 이를 통해 개발자는 요소가 처리될 때까지 <link>
, <script>
또는 <style>
요소를 렌더링 차단으로 명시적으로 표시할 수 있지만 그동안 파서가 문서 처리를 계속할 수 있습니다.
파서 차단 리소스
파서 차단 리소스는 브라우저가 HTML을 계속 파싱하여 다른 작업을 찾지 못하도록 하는 리소스입니다. JavaScript는 실행 시 DOM 또는 CSSOM을 변경할 수 있으므로 기본적으로 파서 차단입니다 (비동기식 또는 지연됨으로 명시적으로 표시되지 않는 한). 따라서 요청된 JavaScript가 페이지의 HTML에 미치는 전체적인 영향을 알 때까지 브라우저는 다른 리소스를 계속 처리할 수 없습니다. 따라서 동기식 JavaScript는 파서를 차단합니다.
파서 차단 리소스는 사실상 렌더링 차단 리소스이기도 합니다. 파서는 완전히 처리될 때까지 파싱을 차단하는 리소스를 지나갈 수 없으므로 그 이후의 콘텐츠에 액세스하고 렌더링할 수 없습니다. 브라우저는 대기하는 동안 지금까지 수신된 HTML을 렌더링할 수 있지만, 중요한 렌더링 경로가 우려되는 경우 <head>
의 파서 차단 리소스는 모든 페이지 콘텐츠가 렌더링되지 못하도록 차단한다는 의미입니다.
파서를 차단하면 렌더링을 차단하는 것보다 훨씬 더 큰 성능 비용이 발생할 수 있습니다. 따라서 브라우저는 기본 HTML 파서가 차단된 동안 미리 로드 스캐너라는 보조 HTML 파서를 사용하여 향후 리소스를 다운로드하여 이 비용을 줄이려고 합니다. HTML을 실제로 파싱하는 것만큼 좋지는 않지만, 적어도 브라우저의 네트워킹 함수가 차단된 파서보다 먼저 작동할 수 있습니다. 즉, 향후 다시 차단될 가능성이 줄어듭니다.
차단 리소스 식별
많은 성능 감사 도구는 렌더링 및 파서 차단 리소스를 식별합니다. WebPageTest는 렌더링 차단 리소스를 리소스 URL 왼쪽에 주황색 원으로 표시합니다.
렌더링을 시작하려면 먼저 모든 렌더링 차단 리소스를 다운로드하고 처리해야 합니다. 이는 폭포식 차트에서 연한 녹색 실선으로 표시됩니다.
Lighthouse는 렌더링을 차단하는 리소스도 강조 표시하지만 리소스가 실제로 페이지 렌더링을 지연하는 경우에만 더 미묘한 방식으로 표시합니다. 이렇게 하면 렌더링 차단을 최소화하는 과정에서 거짓양성을 방지하는 데 도움이 됩니다. Lighthouse를 통해 이전 WebPageTest 그림과 동일한 페이지 URL을 실행하면 스타일시트 중 하나만 렌더링 차단 리소스로 식별됩니다.
중요한 렌더링 경로 최적화
중요한 렌더링 경로를 최적화하려면 이전 모듈에 설명된 대로 HTML을 수신하는 데 걸리는 시간 (첫 바이트까지의 시간 (TTFB) 측정항목으로 표시됨)을 줄이고 렌더링 차단 리소스의 영향을 줄여야 합니다. 이러한 개념은 다음 모듈에서 살펴봅니다.
중요한 콘텐츠가 포함된 렌더링 경로
오랫동안 중요한 렌더링 경로는 초기 렌더링에만 관심을 기울였습니다. 그러나 웹 성능에 관한 사용자 중심 측정항목이 점점 늘어나면서 중요한 렌더링 경로의 종점은 첫 번째 페인트여야 하는지 아니면 그 이후에 이어지는 더 많은 콘텐츠가 포함된 페인트 중 하나여야 하는지에 대한 의문이 제기되고 있습니다.
대신 콘텐츠가 포함된 렌더링 경로 (다른 사람들이 부르는 키 경로)의 일부로 콘텐츠가 포함된 최대 페인트 (LCP) 또는 콘텐츠가 포함된 첫 페인트 (FCP)까지의 시간에 집중하는 것도 방법입니다. 이 경우 필수 렌더링 경로의 일반적인 정의와 같이 반드시 차단되지는 않지만 콘텐츠가 포함된 페인트를 렌더링하는 데 필요한 리소스를 포함해야 할 수 있습니다.
'중요'의 정확한 정의와 관계없이 초기 렌더링을 지연시키는 요소와 주요 콘텐츠를 이해하는 것이 중요합니다. 첫 페인트는 사용자에게 무엇이든 렌더링할 수 있는 첫 번째 기회를 측정합니다. 이상적으로는 배경 색상과 같은 것이 아니라 의미 있는 것이어야 하지만 콘텐츠가 없더라도 사용자에게 무언가를 표시하는 데는 여전히 가치가 있습니다. 이는 기존에 정의된 것처럼 중요한 렌더링 경로를 측정하기 위한 근거입니다. 동시에 기본 콘텐츠가 사용자에게 표시되는 시점을 측정하는 것도 중요합니다.
콘텐츠가 포함된 렌더링 경로 식별
많은 도구에서 LCP 요소와 렌더링 시점을 식별할 수 있습니다. Lighthouse는 LCP 요소 외에도 LCP 단계와 각 단계에 소요된 시간을 파악하여 최적화 작업에 가장 집중해야 할 부분을 파악하는 데도 도움이 됩니다.
더 복잡한 사이트의 경우 Lighthouse는 별도의 감사에서 중요한 요청 체인을 강조 표시합니다.
이 Lighthouse 감사는 높은 우선순위로 로드된 모든 리소스를 관찰하므로 실제로 렌더링을 차단하지 않더라도 Chrome에서 높은 우선순위 리소스로 설정하는 웹 글꼴 및 기타 콘텐츠가 포함됩니다.
학습한 내용 테스트
중요한 렌더링 경로는 무엇을 의미하나요?
중요한 렌더링 경로에 관련된 리소스는 무엇인가요?
<head>
요소의 렌더링 차단 CSS<head>
요소의 렌더링 차단 JavaScript렌더링 차단이 페이지 렌더링에 필요한 이유는 무엇인가요?
JavaScript가 HTML 파서를 차단하는 이유는 무엇인가요 (<script>
요소에 defer
, async
또는 module
속성이 지정되지 않은 경우)?
<script>
는 파서 차단 및 렌더링 차단입니다.다음 단계: 리소스 로드 최적화
이 모듈에서는 브라우저가 웹페이지를 렌더링하는 방식에 관한 몇 가지 이론과 특히 페이지의 초기 렌더링을 완료하는 데 필요한 사항을 다뤘습니다. 다음 모듈에서는 리소스 로드를 최적화하는 방법을 알아보고 이 렌더링 경로를 최적화하는 방법을 살펴봅니다.