주요 렌더링 경로란 웹페이지가 브라우저에서 렌더링을 시작할 때까지 관련된 단계를 의미합니다. 페이지를 렌더링하려면 브라우저에 HTML 문서 자체뿐만 아니라 해당 문서를 렌더링하는 데 필요한 모든 중요 리소스가 필요합니다.
HTML 문서를 브라우저로 가져오는 방법은 이전의 일반 HTML 성능 고려사항 모듈에서 다뤘습니다. 그러나 이 모듈에서는 브라우저가 HTML 문서를 다운로드한 후에 페이지를 렌더링하기 위해 무엇을 하는지 자세히 알아보겠습니다.
프로그레시브 렌더링
웹은 자연적으로 배포되어 있습니다. 사용하기 전에 설치되는 네이티브 애플리케이션과 달리 브라우저는 페이지 렌더링에 필요한 모든 리소스가 있는 웹사이트에 의존할 수 없습니다. 따라서 브라우저는 페이지를 점진적으로 렌더링하는 데 매우 능숙합니다. 네이티브 앱에는 일반적으로 설치 단계와 실행 단계가 있습니다. 그러나 웹페이지와 웹 앱의 경우 이 두 단계 간의 경계가 훨씬 덜하며 브라우저는 이를 염두에 두고 특별히 설계되었습니다.
브라우저에서 페이지를 렌더링할 수 있는 리소스가 확보되면 일반적으로 렌더링이 시작됩니다. 따라서 선택은 렌더링 시점에 관한 것입니다. 너무 이른 시기는 언제인가요?
브라우저에 일부 HTML만 있을 때(CSS 또는 필요한 자바스크립트가 있는 경우) 최대한 빨리 렌더링되면 페이지가 잠시 깨져서 최종 렌더링을 위해 크게 변경됩니다. 이는 브라우저가 더 나은 사용자 환경을 제공하는 초기 렌더링에 필요한 리소스를 더 많이 확보할 때까지 처음에 빈 화면을 표시하는 것보다 좋지 않습니다.
반면 브라우저가 순차적 렌더링을 수행하는 대신 모든 리소스를 사용할 수 있을 때까지 대기하면 사용자는 오랫동안 대기하게 되며, 훨씬 이전 시점에 페이지를 사용할 수 있었다면 불필요하게 대기하는 경우가 많습니다.
브라우저는 명백히 손상된 환경을 표시하지 않도록 하기 위해 기다려야 하는 최소 리소스 수를 알아야 합니다. 반면 브라우저는 필요한 콘텐츠보다 오래 기다리지 않은 상태에서 사용자에게 콘텐츠를 표시해서는 안 됩니다. 초기 렌더링을 수행하기 전에 브라우저가 거치는 단계를 주요 렌더링 경로라고 합니다.
핵심 렌더링 경로를 이해하면 초기 페이지 렌더링이 필요 이상으로 차단되지 않도록 하여 웹 성능을 개선할 수 있습니다. 그러나 동시에 중요한 렌더링 경로에서 초기 렌더링에 필요한 리소스를 삭제하여 렌더링이 너무 일찍 일어나지 않도록 하는 것이 중요합니다.
(중요) 렌더링 경로
렌더링 경로에는 다음 단계가 포함됩니다.
- HTML에서 DOM (Document Object Model) 생성
- CSS에서 CSS 개체 모델 (CSSOM) 생성
- DOM 또는 CSSOM을 변경하는 자바스크립트 적용
- 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 및 자바스크립트를 이해해야 합니다.
렌더링 차단 리소스
일부 리소스는 매우 중요한 것으로 간주되어 브라우저가 처리할 때까지 페이지 렌더링을 일시중지합니다. CSS는 기본적으로 이 카테고리에 속합니다.
브라우저에서 CSS(<style>
요소의 인라인 CSS 또는 <link rel=stylesheet href="...">
요소에 의해 지정된 외부 참조 리소스)를 확인하면 브라우저는 해당 CSS의 다운로드 및 처리를 완료할 때까지 더 이상 콘텐츠를 렌더링하지 않습니다.
리소스가 렌더링을 차단한다고 해서 브라우저가 다른 작업을 하지 못하게 하는 것은 아닙니다. 브라우저는 최대한 효율성을 높이려고 합니다. 따라서 브라우저는 CSS 리소스를 다운로드해야 하는 경우 리소스를 요청하고 렌더링을 일시중지하지만 나머지 HTML을 계속 처리하고 그동안 다른 작업을 찾습니다.
CSS와 같은 렌더링 차단 리소스는 발견 시 페이지의 모든 렌더링을 차단하는 데 사용됩니다. 즉, 일부 CSS가 렌더링을 차단하는지 여부는 브라우저에서 검색했는지에 따라 다릅니다. 일부 브라우저 (처음에는 Firefox, 지금은 Chrome)에서는 렌더링 차단 리소스 아래의 콘텐츠 렌더링만 차단합니다. 즉, Google은 중요한 렌더링 차단 경로의 경우 일반적으로 <head>
의 렌더링 차단 리소스에 관심이 있습니다. 이러한 리소스는 전체 페이지의 렌더링을 효과적으로 차단하기 때문입니다.
최근의 혁신 기능은 Chrome 105에 추가된 blocking=render
속성입니다. 이를 통해 개발자는 요소가 처리될 때까지 <link>
, <script>
또는 <style>
요소를 렌더링 차단으로 명시적으로 표시할 수 있으며, 그동안도 파서가 계속해서 문서를 처리하도록 허용할 수 있습니다.
파서 차단 리소스
파서 차단 리소스는 HTML을 계속 파싱하여 브라우저가 실행할 다른 작업을 찾지 못하게 하는 리소스입니다. JavaScript는 실행 시 DOM 또는 CSSOM을 변경할 수 있기 때문에 기본적으로 JavaScript는 파서를 차단합니다 (특별히 비동기 또는 지연으로 표시된 경우 제외)입니다. 따라서 요청된 자바스크립트가 페이지 HTML에 미치는 영향을 완전히 파악할 때까지는 브라우저가 다른 리소스를 계속 처리할 수 없습니다. 따라서 동기 JavaScript는 파서를 차단합니다.
파서 차단 리소스는 렌더링도 효과적으로 차단합니다. 파서는 완전히 처리될 때까지 파싱 차단 리소스를 지나 계속할 수 없으므로 리소스 이후의 콘텐츠에 액세스하거나 렌더링할 수 없습니다. 브라우저는 대기하는 동안 수신한 모든 HTML을 렌더링할 수 있지만, 주요 렌더링 경로와 관련된 경우 <head>
의 파서 차단 리소스는 사실상 모든 페이지 콘텐츠의 렌더링이 차단되었음을 의미합니다.
파서를 차단하면 단순히 렌더링을 차단하는 것 이상으로 성능 비용이 훨씬 많이 발생할 수 있습니다. 따라서 기본 HTML 파서가 차단된 동안에는 브라우저에서 미리 로드된 스캐너라고 하는 보조 HTML 파서를 사용하여 향후 리소스를 다운로드하여 이 비용을 줄이려고 합니다. 실제로 HTML을 파싱하는 것만큼 좋지는 않지만 브라우저의 네트워킹 함수가 차단된 파서보다 먼저 작동하도록 합니다. 즉, 향후 다시 차단될 가능성이 낮습니다.
차단 리소스 식별
많은 성능 감사 도구는 렌더링 및 파서 차단 리소스를 식별합니다. WebPageTest는 렌더링 차단 리소스를 리소스 URL 왼쪽에 있는 주황색 원으로 표시합니다.
![WebPageTest에서 생성된 네트워크 폭포식 구조 다이어그램의 스크린샷 파서 차단 리소스는 리소스의 URL 왼쪽에 주황색 원으로 표시되며, 렌더링 시작 시간은 진한 녹색 실선으로 식별됩니다.](https://web.developers.google.cn/static/learn/performance/understanding-the-critical-path/image/fig-2.png?authuser=9&hl=ko)
렌더링을 차단하는 모든 리소스는 렌더링을 시작하기 전에 다운로드하고 처리해야 하며, 이는 폭포식 구조에서 진한 녹색 실선으로 표시됩니다.
Lighthouse는 렌더링 차단 리소스도 강조 표시하지만, 리소스가 실제로 페이지 렌더링을 지연시키는 경우에만 좀 더 정교한 방식으로 강조합니다. 이렇게 하면 렌더링 차단을 최소화하는 거짓양성을 방지하는 데 도움이 될 수 있습니다. Lighthouse를 통해 이전 WebPageTest 그림과 동일한 페이지 URL을 실행하면 스타일시트 중 하나만 렌더링 차단 리소스로 식별됩니다.
![렌더링 차단 리소스 제거를 위한 Lighthouse 감사 스크린샷 감사에는 렌더링을 차단하는 리소스와 이러한 리소스가 차단한 시간이 표시됩니다.](https://web.developers.google.cn/static/learn/performance/understanding-the-critical-path/image/fig-3.png?authuser=9&hl=ko)
주요 렌더링 경로 최적화
핵심 렌더링 경로를 최적화하려면 이전 모듈에서 설명한 대로 HTML (첫 바이트까지의 시간 (TTFB) 측정항목으로 표현됨)을 수신하는 데 걸리는 시간을 줄이고 렌더링 차단 리소스의 영향을 줄여야 합니다. 이러한 개념은 다음 모듈에서 알아봅니다.
중요 콘텐츠가 포함된 렌더링 경로
오랫동안 주요 렌더링 경로 자체는 초기 렌더링과 관련이 있었습니다. 그러나 웹 성능에 관한 더 사용자 중심 측정항목이 등장하여 중요한 렌더링 경로의 엔드포인트가 첫 번째 페인트여야 하는지, 아니면 그 이후에 이어지는 콘텐츠가 더 많은 페인트 중 하나가 되어야 하는지 의문이 생길 수 있습니다.
대안으로는 콘텐츠 렌더링 경로 (또는 키 경로라고도 함)의 일부로 최대 콘텐츠 페인트 (LCP) 또는 첫 콘텐츠 페인트 (FCP)까지의 시간에 집중하는 방법이 있습니다. 이 경우 주요 렌더링 경로의 일반적인 정의에서처럼 반드시 차단하지는 않지만 콘텐츠가 포함된 페인트를 렌더링하는 데 필요한 리소스를 포함해야 할 수 있습니다.
'중요'하다고 정의하는 정확한 정의와 관계없이 초기 렌더링을 방해하는 요소와 주요 콘텐츠를 이해하는 것이 중요합니다. 첫 번째 페인트는 사용자에게 모든 것을 렌더링할 수 있는 첫 번째 기회를 측정합니다. 이상적으로는 배경 색상과 같은 것이 아닌 의미 있는 것이어야 하지만 콘텐츠가 포함되어 있지 않더라도 무엇을 사용자에게 표시하는 것은 여전히 가치가 있습니다. 이는 전통적으로 정의된 주요 렌더링 경로 측정을 위한 인수입니다. 동시에 주요 콘텐츠가 사용자에게 표시되는 시점을 측정하는 데도 가치가 있습니다.
콘텐츠 렌더링 경로 식별
많은 도구에서 LCP 요소와 렌더링 시점을 식별할 수 있습니다. Lighthouse는 LCP 요소 외에도 LCP 단계와 각 단계에 소요된 시간을 파악하여 최적화 노력을 어디에 집중해야 할지 파악하는 데 도움을 줍니다.
![페이지의 LCP 요소와 TTFB, 로드 지연, 로드 시간, 렌더링 지연과 같은 단계별 소요 시간을 보여주는 Lighthouse LCP 감사 스크린샷](https://web.developers.google.cn/static/learn/performance/understanding-the-critical-path/image/fig-4.png?authuser=9&hl=ko)
더 복잡한 사이트의 경우 별도의 감사에서 Lighthouse는 중요 요청 체인도 강조 표시합니다.
![다른 주요 리소스 아래에 중첩된 주요 리소스와 중요한 요청 체인과 관련된 총 지연 시간을 보여주는 Lighthouse 중요 요청 체인 다이어그램의 스크린샷](https://web.developers.google.cn/static/learn/performance/understanding-the-critical-path/image/fig-5.png?authuser=9&hl=ko)
Lighthouse 감사는 높은 우선순위로 로드된 모든 리소스를 관찰합니다. 따라서 실제로 렌더링 차단이 아니더라도 Chrome에서 우선순위가 높은 리소스로 설정한 웹 글꼴 및 기타 콘텐츠를 포함합니다.
학습한 내용 테스트
핵심 렌더링 경로는 무엇을 의미하나요?
주요 렌더링 경로와 관련된 리소스는 무엇입니까?
<head>
요소의 렌더링 차단 CSS<head>
요소의 렌더링 차단 JavaScript렌더링 차단이 페이지 렌더링에서 필요한 부분인 이유는 무엇인가요?
JavaScript가 HTML 파서를 차단하는 이유는 무엇인가요 (<script>
요소에 defer
, async
또는 module
속성이 지정되지 않았다고 가정함)?
<script>
은 파서를 차단하고 렌더링을 차단합니다.다음 과정: 리소스 로드 최적화
이 모듈에서는 브라우저가 웹페이지를 렌더링하는 방식과 특히 페이지의 초기 렌더링을 완료하는 데 필요한 사항에 대한 이론을 다루었습니다. 다음 모듈에서는 리소스 로드를 최적화하는 방법을 학습하여 이 렌더링 경로를 최적화하는 방법을 알아봅니다.