중요 렌더링 경로 (Critical Rendering Path) 최적화: 중요 자원 수 최소화
2025. 8. 23.
개요
브라우저는 HTML을 파싱하다가 <script> 태그를 만나면 자원을 로드하고 실행할 때까지 파싱을 중단한다. 이러한 '렌더링 차단' 현상은 스크립트의 크기가 크거나 네트워크 환경이 좋지 않을 때 사용자 경험을 저하시키는 원인이 된다. 이를 효율적으로 제어하기 위해 defer와 async 속성을 활용할 수 있다.
기본
아무런 속성이 없는 일반적인 스크립트 태그는 다음과 같이 동작한다.
- HTML 파싱을 하다가 스크립트를 만나면 즉시 파싱을 멈춘다.
- 스크립트 파일을 다운로드하고 실행이 완료될 때까지 파싱은 중단된 상태로 유지된다.
- 스크립트가 DOM 요소에 접근해야 하는 경우, 태그 위치보다 아래에 있는 요소는 아직 생성되지 않아 에러가 발생할 수 있다.
async
async 속성은 비동기(Asynchronous) 로드를 의미한다.
- HTML 파싱과 스크립트 다운로드를 병렬로 진행한다.
- 다운로드가 완료되면 그 즉시 파싱을 멈추고 스크립트를 실행한다.
- 실행 시점의 불확실성: 여러개의 스크립트가 있을 경우, 먼저 다운로드된 순서대로 실행된다. 따라서 실행 순서가 중요한 스크립트에는 적합하지 않다.
- 방문자 통계 분석이나 광고 스크립트처럼 페이지의 핵심 로직과 독립적인 자원에 주로 사용된다.
defer
defer 속성은 실행 지연(Deferred)을 의미한다.
- HTML 파싱과 스크립트 다운로드를 병렬로 진행한다.
async와 다른 점은 HTML 파싱이 완전히 완료된 후에만 스크립트를 실행한다는 것이다.- 순서 보장: 여러 개의 스크립트가 있어도 문서에 명시된 순서대로 실행된다.
- DOM의 모든 요소가 준비된 상태에서 실행되므로, 프론트엔드 개발에서 가장 범용적으로 권장되는 방식이다.
정리
| 속성 | 파싱 중단 시점 | 실행 시점 | 실행 순서 |
|---|---|---|---|
| 기본 ( | 다운로드 및 실행 시 | 즉시 | 명시된 순서 |
| async | 다운로드 완료 후 실행 시 | 다운로드 완료 즉시 | 다운로드 완료 순 (무작위) |
| defer | 없음 | HTML 파싱 완료 후 | 명시된 순서 |
- async를 사용하는 경우: 스크립트가 페이지의 다른 요소나 스크립트에 의존하지 않고, 최대한 빨리 실행되어야 하는 경우 선택한다.
- defer를 사용하는 경우: 스크립트가 DOM 구조 전체에 의존하거나, 여러 스크립트 간의 실행 순서가 중요한 경우 선택한다.
인라인 스크립트(src 속성이 없는 경우) 에는 async와 defer 모두 적용되지 않는다.
type="module"로 선언된 모듈 스크립트는 기본적으로 defer처럼 동작한다. 여기에 async를 추가하면 async처럼 동작하게 할 수 있다.