LCP 리소스 로드 지연 최적화
지연에서 화면 표시까지: Largest Contentful Paint의 리소스 로드 지연 구간을 개선하는 방법을 알아보자.
이 가이드는 Largest Contentful Paint (LCP) 허브의 일부입니다. Resource Load Delay는 특히 SPA 사이트에서 나쁜 LCP 점수의 가장 큰 원인인 경우가 많습니다!
LCP Resource Load Delay 최적화하기
Largest Contentful Paint (LCP)는 4가지 LCP 하위 단계인 TTFB, Resource Load Delay, Resource Load Duration, Element Render Delay 중 하나입니다.
간단한 팁: LCP가 이미지인 경우 거의 항상 텍스트보다 결과가 나쁩니다. RUM 데이터에서 LCP 요소 유형을 추적해야 합니다. 그렇지 않으면 아무것도 모른 채 작업하는 것과 같습니다.
Table of Contents!
- LCP Resource Load Delay 최적화하기
- Resource Load Delay란 무엇인가?
- 브라우저는 LCP 요소를 어떻게 찾는가?
- Core Web Vitals에서 Load Delay가 중요한 이유
- Resource Load Delay를 감지하는 방법
- 일반적인 원인 및 영향력이 큰 해결책
- 리소스 힌트를 사용한 고급 우선순위 지정
- <link rel="preload">로 조기 발견 강제하기
- fetchpriority="high"와 브라우저의 우선순위 대기열
- 서드파티 연결 최적화: preconnect 및 dns-prefetch
- 표: LCP 최적화를 위한 리소스 힌트 비교
- 총체적이고 미래지향적인 전략
- 최신 CDN의 역할
- Speculation Rules로 지연 완전히 없애기
- 사례 연구 종합: 이론에서 실제까지
- Load Delay 개선 방법
- 다음 단계: LCP 최적화 계속하기
Resource Load Delay란 무엇인가?
Resource Load Delay는 TTFB와 브라우저가 LCP 리소스 다운로드를 시작하는 시점 사이의 시간입니다. 기본적으로 브라우저는 가능한 한 빨리 LCP 리소스(예: LCP 이미지)를 대기열에 추가해야 합니다. 가능한 한 빨리 대기열에 추가되지 않는다면 브라우저가 즉시 발견하지 못했거나 충분히 중요하다고 인식하지 못했기 때문일 가능성이 높습니다.
이 값이 높다는 것은 브라우저가 초기 HTML payload에서 리소스 URL을 찾을 수 없는 아키텍처 문제를 의미합니다. 이 Resource Load Delay는 브라우저가 LCP 리소스가 필요하다는 것을 식별하고 이를 가져오기로 결정하는 데 소비하는 시간으로 볼 수 있습니다.
또한 Resource Load Delay는 리소스가 실제로 로드되기 전에 발생한다는 점을 이해하는 것이 중요합니다. 그렇기 때문에 반응형 이미지나 WebP, AVIF 같은 새로운 이미지 포맷과는 아무런 관련이 없습니다.

시스템 폰트를 사용하여 렌더링되는 텍스트 기반 LCP 요소의 경우, 외부 리소스를 가져올 필요가 없으므로 이 Resource Load Delay는 일반적으로 0입니다. Resource Load Delay 값이 높게 나타나는 현상은 이미지나 비디오 파일 같은 외부 네트워크 리소스에 의존하는 LCP 요소에만 해당합니다.
브라우저는 LCP 요소를 어떻게 찾는가?
Resource Load Delay를 줄이려면 브라우저가 어떻게 리소스를 발견하는지(최소한 LCP 요소를 어떻게 발견하는지) 이해해야 합니다. 브라우저는 빠른 경로(fast path)와 느린 경로(slow path)라는 두 가지 메커니즘을 사용합니다. 먼저 LCP 요소가 '빠른 경로'에 있는지 확인해야 합니다.

- DOM 파서 (느린 경로): 이것은 브라우저의 메인 파서이며 처리할 작업이 매우 많습니다. HTML, CSS(stylesheets)를 읽고 JavaScript와 상호 작용하여 전체 페이지를 구축합니다. 다른 파일이 먼저 다운로드되고 실행됨에 따라 지연 및 중단될 수 있으며, 지연을 유발하는 종속성 체인을 만들기 때문에 이는 느린 경로입니다.
- 프리로드 스캐너 (빠른 경로): DOM 파서는 (상대적으로) 느리기 때문에 브라우저에는 다운로드 가능한 리소스를 매우 빠르게 스캔하고 어떤 작업에도 중단되지 않는 번개처럼 빠른 보조 스캐너가 있습니다. <script>, lazy loading이 아닌 <img> 또는 <link> 태그를 찾으면 CSS가 파싱되거나 JavaScript가 실행되기 전에 즉시 다운로드 대기열에 추가합니다. 이것이 모든 중요 리소스를 위한 최적의 경로입니다.
Resource Load Delay 최적화를 위한 전체 전략은 한 가지 원칙을 바탕으로 합니다. 프리로드 스캐너가 가능한 한 빨리 LCP 리소스 URL을 발견할 수 있게 해야 합니다.
이는 LCP 요소에 대해 2가지를 의미합니다.
- loading="lazy" 속성이 없는 일반 이미지 태그를 사용하여 프리로드 스캐너가 찾을 수 있도록 하십시오.
- 프리로드 스캐너가 덜 중요한 리소스를 너무 많이 우선시하지 않도록 하십시오.
Core Web Vitals에서 Load Delay가 중요한 이유
초보 개발자는 종종 LCP를 "파일 크기" 문제라고 생각합니다. 이로 인해 팀은 이미지 압축, 최신 이미지 포맷 및 반응형 이미지에 집중하게 됩니다. 이것은 실수입니다. 우리의 Core Web Vitals 자체 연구에 따르면 LCP의 가장 큰 단일 병목은 TTFB(48%)이고 그 다음이 Load Delay(24%)이며, 로드 시간은 10%에 불과하고 Render delay가 17%를 차지합니다.

여기서 중요한 점은 TTFB는 항상 존재하는 반면 Load Delay는 거의 완전히 고칠 수 있다는 것입니다. 따라서 Load Delay가 최적화 잠재력이 가장 높은 요소입니다.
Resource Load Delay를 감지하는 방법
Resource Load Delay를 고치려면 먼저 정확하게 측정해야 합니다. 작업 흐름은 항상 동일합니다. CrUX로 확인하여 실제 사용자 데이터(RUM)로 문제를 먼저 정의한 다음, 심층 분석을 위해 Chrome DevTools로 넘어갑니다.
1단계: CrUX로 확인하기
CrUX는 적격한 Chrome 사용자로부터 수집된 구글의 공개 실제 사용자 field data로, 75백분위수에서 Core Web Vitals의 28일 롤링 뷰로 제공됩니다. 수치가 좋은지 나쁜지는 알려주지만 누가, 무엇을, 왜 그랬는지는 알려주지 않습니다. 구글이 CrUX 데이터를 신뢰하므로 이것이 시작점으로서 가장 좋은 정보 소스입니다.
cruxvis.withgoogle.com으로 이동하여 웹사이트를 입력한 다음 Loading Performance로 이동하여 Largest Contentful Paint (LCP) image subparts를 클릭하십시오.

2단계: field data(RUM) 분석하기
RUM은 모든 실제 사용자의 Core Web Vitals를 수집하여 훨씬 더 구체적이고 상세한 뷰를 제공합니다. 누가, 무엇을 했는지 원하는 방식으로 세분화하여 알려주지만(이 정보는 매우 귀중함), 왜 그런지는 알려주지 않습니다.
예를 들어 이 CoreDash 스크린샷은 어떤 URL이 Resource Load Delay(녹색)를 겪고 있는지 알려줍니다.

3단계: DevTools로 진단하기
RUM 데이터에서 대상 페이지와 LCP 요소를 식별했다면, Chrome DevTools를 사용하여 원인을 진단합니다. 여기서 목표는 문제를 재현하고 LCP 하위 단계를 측정하여 정확한 Resource Load Delay 값을 얻는 것입니다. 또한 DevTools는 main thread 분석을 수행하여 어떤 작업이 실행 중이고 렌더링 프로세스를 차단할 가능성이 있는지 정확히 확인하는 곳이기도 합니다.

단계별 가이드: 이 작업 흐름에 대한 전체 가이드를 작성했습니다. Chrome DevTools 성능 패널로 LCP 진단하기. 여기서는 스로틀링 설정, 트레이스 기록, LCP 세부 정보 분석에서 정확한 Resource Load Delay 값을 읽는 방법을 다룹니다.
일반적인 원인 및 영향력이 큰 해결책
높은 Resource Load Delay는 두 가지 중 하나로 인해 발생합니다. LCP 리소스가 늦게 발견되거나 페치 우선순위가 낮게 부여된 것입니다. 다음은 가장 일반적인 아키텍처 실수와 그 해결책입니다.
원인: CSS를 통해 로드된 LCP
문제: 프리로드 스캐너는 CSS 파일을 파싱하지 않습니다. LCP 이미지가 CSS background-image로 정의된 경우, 이 고속 스캐너에는 해당 URL이 보이지 않습니다. 브라우저는 HTML을 다운로드하고, CSS 파일 링크를 찾고, CSS 파일을 다운로드하고, CSSOM을 구축한 다음 스타일을 적용한 후에야 이미지를 발견할 수 있습니다. 이러한 종속성 체인이 높은 Resource Load Delay를 직접적으로 유발합니다. 이 패턴에 대한 자세한 내용은 배경 이미지 지연 가이드를 참조하십시오.
해결책: 올바른 구현은 중요한 LCP 요소에 background-image를 사용하지 않는 것입니다. 대신 표준 <img> 태그를 사용하십시오. 이렇게 하면 이미지 URL이 HTML에 직접 배치되어 프리로드 스캐너가 즉시 찾을 수 있습니다. CSS를 사용하여 동일한 시각적 결과를 얻을 수 있습니다.
구현 예시:
안티 패턴 (이렇게 하지 마십시오):
<!-- CSS -->
.hero {
background-image: url('hero-image.jpg');
height: 500px;
width: 100%;
}
<!-- HTML -->
<div class="hero"></div>
모범 사례 (대신 이렇게 하십시오):
<!-- HTML -->
<div class="hero-container">
<img
src="hero-image.jpg"
alt="히어로 이미지를 위한 설명 alt 텍스트"
fetchpriority="high"
class="hero-background-img"
width="1200"
height="500"
/>
<div class="hero-content">
<h1>페이지 제목</h1>
</div>
</div>
<!-- CSS -->
.hero-container {
position: relative;
height: 500px;
width: 100%;
}
.hero-background-img {
position: absolute;
inset: 0; /* top: 0; right: 0; bottom: 0; left: 0;과 동일 */
width: 100%;
height: 100%;
object-fit: cover; /* 이 속성은 background-size: cover를 모방합니다 */
z-index: -1; /* 이미지를 다른 콘텐츠 뒤에 배치합니다 */
}
이 구현은 동일한 시각적 결과를 제공하지만 LCP 이미지를 가능한 한 가장 이른 순간에 발견할 수 있게 하여 Load Delay를 최소화합니다.
원인: 클라이언트 사이드 렌더링 및 JavaScript 주입
문제: React 또는 Vue와 같은 클라이언트 사이드 렌더링(CSR) 프레임워크를 사용하는 애플리케이션은 종종 최소한의 HTML 셸만 제공합니다. LCP <img> 태그를 포함한 실제 콘텐츠는 대용량 프레임워크 번들이 다운로드, 파싱, 실행된 후에야 JavaScript에 의해 DOM에 삽입됩니다. 이 프로세스는 근본적으로 프리로드 스캐너에서 LCP 리소스를 숨기므로, 발견 대기 시간이 길어집니다.
해결책: 가장 효과적인 해결책은 초기 렌더링을 클라이언트에서 서버로 옮기는 것입니다.
- 서버 사이드 렌더링(SSR) 또는 정적 사이트 생성(SSG): SSR 또는 SSG와 같은 아키텍처 패턴은 서버에서 전체 HTML을 생성합니다. 브라우저는 <img> 태그와 src 속성이 포함된 완전한 문서를 받으므로, 프리로드 스캐너가 LCP 리소스를 즉시 발견할 수 있습니다. 성능이 중요한 모든 페이지에 필수적인 아키텍처입니다.
- 프레임워크별 최적화: 최신 프레임워크는 내장된 최적화 기능도 제공합니다. 예를 들어 Next.js <Image> 컴포넌트에는 priority 속성이 있습니다. 이것을 true로 설정하면 프레임워크가 올바른 <link rel="preload"> 및 fetchpriority="high" 속성을 자동으로 추가하도록 지시하여 이미지가 올바른 우선순위로 발견되고 페치되도록 보장합니다.
원인: LCP 이미지에 loading="lazy" 사용
문제: 이것은 빈번하게 발생하며 영향이 큰 실수입니다. loading="lazy" 속성은 viewport에 가까워질 때까지 이미지 페치를 지연시키라는 브라우저에 대한 직접적인 지시입니다. 이는 스크롤 아래(below-the-fold) 이미지에 대한 올바른 최적화이지만, 스크롤 위(above-the-fold) LCP 요소에 적용하는 것은 역효과를 냅니다. 브라우저의 프리로드 스캐너는 loading="lazy"가 있는 이미지를 무시하도록 설계되었으므로 발견이 늦어지고 Resource Load Delay가 높아집니다.
해결책: 해결하려면 세심한 주의가 필요합니다.
- LCP 이미지에서 loading="lazy" 제거: LCP 요소가 될 가능성이 있는 모든 이미지에는
loading="lazy"속성이 없어야 합니다. 브라우저의 기본 동작은loading="eager"이며, 이는 중요한 스크롤 위(above-the-fold) 콘텐츠에 대한 올바른 설정입니다. loading 속성을 완전히 생략해도 동일한 효과가 있습니다. - 서드파티 도구 감사 및 구성: 서드파티 도구도 감사해야 합니다. WordPress와 같은 많은 CMS 플랫폼과 다양한 이미지 최적화 플러그인은 모든 이미지에 자동으로 lazy loading을 적용합니다. 이러한 동작에서 LCP 이미지를 제외하도록 이 도구들을 구성하는 것이 필수적입니다. 여기에는 종종 페이지의 처음 한두 개 이미지에 대한 제외 규칙을 만드는 작업이 포함됩니다.
원인: 최적화되지 않은 HTML 구조와 큰 문서
문제: 프리로드 스캐너는 HTML 문서를 위에서 아래로 처리합니다. 헤더 아이콘이나 채팅 위젯 스크립트처럼 중요하지는 않지만 대역폭을 많이 사용하는 리소스가 <body>에서 LCP 요소보다 위에 배치되면 먼저 발견되어 다운로드 대기열에 추가됩니다. 이로 인해 초기 네트워크 대역폭이 소모되고 LCP 리소스 다운로드가 지연될 수 있습니다. 큰 HTML 문서도 문제가 될 수 있습니다. LCP 요소가 브라우저가 받는 첫 번째 데이터 청크(약 14KB)에 없으면 발견이 최소 1번의 네트워크 왕복(round trip)만큼 지연됩니다.
해결책: HTML 내에서 콘텐츠의 구조와 우선순위를 최적화하십시오.
- HTML 재정렬: 가능한 경우 LCP 요소의 <img> 태그나 텍스트 블록이 <body> 태그 안에서 최대한 일찍 나타나도록 하십시오.
- 중요하지 않은 이미지 우선순위 낮추기: HTML 소스 초반에 나타나야 하는 중요하지 않은 이미지(예: 헤더의 아이콘)에는
loading="lazy"를 적용하십시오. 이렇게 하면 프리로드 스캐너가 이를 건너뛰도록 지시하여 LCP 요소를 위한 다운로드 대기열을 보존합니다. - 필수적이지 않은 스크립트 지연: 애널리틱스, 광고 또는 소셜 미디어 위젯을 위한 스크립트가 초기 렌더링에 중요한 경우는 드뭅니다.
<script>태그를<body>끝으로 옮기거나defer속성을 사용하십시오. 이렇게 하면 스크립트가 파서를 차단하거나 LCP 리소스와 네트워크 대역폭을 두고 경쟁하는 것을 막을 수 있습니다.
리소스 힌트를 사용한 고급 우선순위 지정
HTML에서 LCP 리소스를 발견할 수 있게 되면, 리소스 힌트를 사용하여 브라우저에 리소스를 가져오는 방법에 대한 보다 명확한 지시를 내릴 수 있습니다. 이러한 힌트는 발견 및 우선순위 지정에 대한 세밀한 제어를 제공합니다.
<link rel="preload">로 조기 발견 강제하기
<link rel="preload">는 힌트가 아니라 지시문입니다. 아직 메인 파서가 발견하지 못했더라도 브라우저가 높은 우선순위로 리소스를 다운로드하도록 강제합니다. 이를 HTML의 <head>에 배치하는 것이 폰트, CSS background image 또는 DOM 깊숙이 위치한 LCP 이미지 같은 리소스의 늦은 발견 문제를 해결하는 가장 직접적인 방법입니다. 전체 구현 세부 정보 및 예시는 LCP 이미지를 프리로드하는 방법에 대한 전용 가이드를 참조하십시오.
메커니즘
HTML 문서의 <head>에 preload 링크를 배치하면, 프리로드 스캐너가 이를 식별하고 지정된 리소스를 즉시 다운로드 대기열에 추가합니다. 이는 외부 스타일시트의 @font-face를 통해 로드되는 폰트, CSS background-image LCP(<img> 태그를 사용하는 것이 좋지만), 또는 복잡한 DOM 구조 깊숙이 위치한 LCP 이미지와 같은 리소스에 이상적입니다.
반응형 프리로드
반응형 이미지를 프리로드할 때는 중요한 구현 세부 사항이 필요합니다. 브라우저가 사용자의 viewport에 맞는 올바른 크기의 이미지를 프리로드하고 낭비적인 이중 다운로드를 피하려면, <link rel="preload"> 태그에 해당 <img> 태그의 속성을 완벽하게 미러링하는 imagesrcset 및 imagesizes 속성이 반드시 포함되어야 합니다.
반응형 프리로드 예시:
<link rel="preload" as="image"
href="lcp-image-large.jpg"
imagesrcset="lcp-image-small.jpg 400w, lcp-image-medium.jpg 800w, lcp-image-large.jpg 1200w"
imagesizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
fetchpriority="high">
<img src="lcp-image-large.jpg"
srcset="lcp-image-small.jpg 400w, lcp-image-medium.jpg 800w, lcp-image-large.jpg 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
alt="설명 alt 텍스트"
fetchpriority="high"
width="1200" height="675">
잠재적 함정
프리로드는 페치 타이밍(Load Delay 및 Resource Load Duration)은 해결하지만 페인트 타이밍은 해결하지 못합니다. 프리로드된 이미지가 도착했을 때 main thread가 무거운 JavaScript나 render blocking CSS로 인해 차단된 상태라면, 이미지는 렌더링될 때까지 기다려야 하므로 병목 지점이 Load Delay에서 Element Render Delay로 이동할 수 있습니다.
fetchpriority="high"와 브라우저의 우선순위 대기열
fetchpriority 속성은 리소스 다운로드의 상대적 중요도를 알리는 힌트입니다. 이를 통해 브라우저 다운로드 대기열 내에서 리소스의 우선순위에 영향을 줄 수 있습니다.
브라우저 우선순위 작동 방식
페이지 로드 중 브라우저가 리소스를 발견하면, 각 리소스에 내부 우선순위 수준을 할당합니다. 기본적으로 viewport의 이미지는 "낮음" 우선순위로 시작하며, 브라우저가 레이아웃을 완료하고 해당 이미지가 표시되는 것을 확인한 후 "높음"으로 업그레이드됩니다. 이 업그레이드를 수행하려면 브라우저가 CSS를 먼저 다운로드하고 파싱해야 하므로 지연이 발생합니다. fetchpriority="high" 속성은 이미지가 발견되는 순간부터 "높음" 우선순위로 설정하여 이 프로세스를 완전히 우회합니다. 우선순위 업그레이드 지연을 제거하므로 LCP 이미지에 특히 큰 영향을 미칩니다.
preload 대 fetchpriority
이 두 힌트는 서로 다르지만 상호 보완적인 목적을 제공합니다. preload는 리소스가 언제 발견되어 대기열에 추가되는지에 영향을 미칩니다. fetchpriority는 리소스가 대기열에 들어간 후의 우선순위 수준에 영향을 미칩니다. 이 차이를 이해하는 것이 중요합니다. preload는 늦은 발견을 해결하는 반면, fetchpriority는 낮은 우선순위를 해결합니다. HTML에 이미 있는 많은 LCP 이미지의 경우 fetchpriority만으로 충분할 수 있습니다. 이들의 상호 작용 방식에 대한 전체 가이드는 리소스 우선순위 지정에 대한 문서를 참조하십시오.
LCP에 대한 모범 사례
LCP 이미지의 경우, 가장 좋은 전략은 둘을 함께 사용하는 것입니다. 첫째, <img> 태그를 HTML 초반에 배치하거나 preload를 사용하여 조기 발견을 보장하십시오. 둘째, <img> 태그(사용하는 경우 preload 링크에도)에 fetchpriority="high"를 직접 추가하십시오. 이 조합은 리소스를 일찍 발견하게 할 뿐만 아니라 스타일시트나 폰트 같은 다른 리소스와의 네트워크 대역폭 경쟁에서 승리할 수 있도록 가능한 최고 우선순위를 부여합니다.
예시:
<img src="lcp-image.jpg" fetchpriority="high" alt="중요한 히어로 이미지">
fetchpriority="low"를 사용해야 할 때
fetchpriority 속성은 우선순위를 높이는 데만 쓰이는 것이 아닙니다. fetchpriority="low"를 사용하여 LCP 이미지와 대역폭을 놓고 경쟁하는 중요하지 않은 리소스의 우선순위를 낮출 수도 있습니다. 일반적인 대상으로는 LCP 요소가 아닌 스크롤 위(above-the-fold) 이미지(예: 헤더의 작은 아이콘이나 아바타)와 필요하지만 시급하지는 않은 프리로드 리소스가 있습니다. 이러한 경쟁 리소스의 우선순위를 명시적으로 낮춤으로써 LCP 이미지를 위한 더 많은 대역폭 여유를 만들 수 있습니다.
<!-- LCP 이미지: 높은 우선순위 -->
<img src="hero.jpg" fetchpriority="high" alt="히어로 이미지" width="1200" height="600">
<!-- 중요하지 않은 스크롤 위 이미지: 낮은 우선순위 -->
<img src="avatar.jpg" fetchpriority="low" alt="작성자 아바타" width="48" height="48"> 입증된 효과
구글 플라이트(Google Flights)의 사례 연구에서, LCP background image에 fetchpriority="high"를 추가한 결과 LCP가 2.6초에서 1.9초로 700ms 개선되었습니다.
서드파티 연결 최적화: preconnect 및 dns-prefetch
문제
LCP 리소스가 이미지 CDN이나 구글 폰트(Google Fonts) 같은 폰트 제공업체 등 서드파티 도메인에서 호스팅되는 경우, 브라우저는 해당 도메인에 대한 새로운 네트워크 연결을 설정해야 합니다. 이 프로세스에는 DNS 조회, TCP 핸드셰이크, TLS 협상이 포함되며, 리소스의 첫 번째 바이트를 다운로드하기 전에 이 모든 작업이 완료되어야 합니다. 이 연결 설정 시간은 cross-origin asset의 Resource Load Delay를 높이는 직접적인 요인입니다.
해결책
preconnect: 이 힌트는 지정된 서드파티 origin에 대한 전체 연결 설정(DNS, TCP 및 TLS)을 백그라운드에서 미리 수행하도록 브라우저에 지시합니다. 리소스가 실제로 요청될 때 연결이 이미 활성화되어 있어 설정 대기 시간을 없애줍니다. 이는 매우 효과적이며 LCP 리소스를 제공하는 가장 중요한 한두 개의 서드파티 도메인에 권장됩니다.dns-prefetch: 도메인에 대한 DNS 조회만 수행하는 가벼운 힌트입니다.preconnect보다 절약되는 시간은 적지만 브라우저 지원이 더 광범위하며 fallback으로 사용하거나 덜 중요한 서드파티 도메인에 유용합니다.
구현 모범 사례
최대 호환성을 보장하려면 두 가지 힌트를 모두 제공하십시오. 브라우저는 지원되는 경우 preconnect를 사용하고 그렇지 않은 경우 dns-prefetch로 fallback합니다. crossorigin 속성은 폰트처럼 CORS를 사용하여 페치되는 리소스에 필수적입니다.
<link rel="preconnect" href="https://my-image-cdn.com" crossorigin>
<link rel="dns-prefetch" href="https://my-image-cdn.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 표: LCP 최적화를 위한 리소스 힌트 비교
오용을 방지하고 이 강력한 힌트들의 고유한 역할을 명확히 하기 위해 다음 표는 비교 요약을 제공합니다.
| 힌트 | 유형 | 주요 목적 | LCP Load Delay에 미치는 영향 | LCP를 위한 최고의 사용 사례 |
|---|---|---|---|---|
preload | 지시문 | 특정 리소스의 조기 페치 강제 | 늦게 발견된 리소스의 발견 지연을 직접적으로 제거 | 늦게 발견된 LCP 이미지(예: CSS background-image) 또는 폰트. |
fetchpriority | 힌트 | 발견된 리소스의 다운로드 우선순위 알림 | 다른 asset보다 우선순위를 높여 대기열 지연 감소 | LCP <img> 태그 자체에 적용하여, 덜 중요한 리소스보다 먼저 다운로드되도록 보장. |
preconnect | 힌트 | 도메인에 대한 전체 네트워크 연결 예열 | cross-origin 연결 설정 시간(DNS, TCP, TLS) 제거 | LCP 이미지 또는 폰트를 호스팅하는 중요한 서드파티 도메인. |
dns-prefetch | 힌트 | 도메인에 대한 DNS 조회만 예열 | cross-origin 연결 시간 중 DNS 조회 부분 감소 | preconnect의 fallback 또는 덜 중요한 서드파티 도메인. |
총체적이고 미래지향적인 전략
리소스 힌트 외에도 더 광범위한 아키텍처 결정으로 Resource Load Delay를 훨씬 더 줄일 수 있습니다.
최신 CDN의 역할
CDN(콘텐츠 전송 네트워크)은 웹 성능을 위한 기반 기술로, 특히 LCP 리소스에 대한 Resource Load Delay를 간접적이지만 상당히 줄여줍니다.
- 연결 오버헤드 감소: 서버의 글로벌 네트워크 전체에 asset을 분산시킴으로써, CDN은 콘텐츠를 지리적으로 사용자에게 더 가깝게 배치합니다. 이는 본질적으로 연결 설정 시간의 구성 요소인 DNS 조회, TCP 핸드셰이크, TLS 협상에 필요한 왕복 시간(RTT)을 줄여줍니다. CDN에서 호스팅되는 LCP 이미지의 경우 이는 Load Delay를 직접적으로 줄여줍니다.
- 이미지 CDN: 특화된 이미지 CDN은 두 배의 이점을 제공합니다. 표준 CDN의 근접성 이점을 제공하는 동시에, 실시간 이미지 크기 조정, 압축, AVIF 및 WebP 같은 최신 포맷으로의 변환 등 Resource Load Duration을 줄이는 많은 복잡한 최적화를 자동화합니다.
- 고급 프로토콜: 많은 최신 CDN은 TCP 대신 QUIC를 사용하는 HTTP/3를 사용합니다. HTTP/3는 연결 설정 시간을 줄이고 head-of-line blocking을 완화하여, 전반적으로 더 빠르고 효율적인 리소스 전송을 이끌어냅니다.
Speculation Rules로 지연 완전히 없애기
Speculation Rules API는 후속 이동에 대한 LCP 지연을 완전히 없앨 수 있습니다.
메커니즘
이 API를 사용하면 사용자가 다음에 이동할 가능성이 높은 URL에 대해 개발자가 브라우저에 선언적으로 알릴 수 있습니다. 이러한 규칙에 따라 브라우저는 사용자가 링크를 클릭하기도 전에 숨겨진 백그라운드 탭에서 대상 페이지를 사전 렌더링(prerender)하도록 선택할 수 있습니다.
LCP에 미치는 영향
사용자가 사전 렌더링된 페이지로 연결되는 링크를 클릭하면 즉각적으로 이동이 이뤄집니다. 페이지는 이미 백그라운드에서 완전히 로드되고 렌더링되었습니다. 이 이동의 경우 사용자 관점에서 TTFB, Resource Load Delay, Resource Load Duration, Element Render Delay가 모두 사실상 0에 가깝게 줄어듭니다.
사용 사례 예시
전자상거래 카테고리 페이지에서 Speculation Rules를 사용해 목록의 처음 몇 개 항목에 대한 제품 상세 페이지를 사전 렌더링할 수 있습니다. 사용자가 이 제품 중 하나를 클릭하면 페이지가 즉시 표시됩니다.
사례 연구 종합: 이론에서 실제까지
이러한 최적화는 실제 환경에서 측정 가능한 영향을 미칩니다.
- 사례 1: 프리로드의 혁신적인 힘: Load Delay가 높은 페이지에서 DebugBear가 수행한 실험은 극적인 예를 제공합니다. LCP 이미지가 요청 체인에 숨겨져 있어 Resource Load Delay가 전체 LCP 시간의 무려 75%를 차지했습니다. 이미지를 일찍 발견할 수 있도록 단일
<link rel="preload">힌트를 구현함으로써 Resource Load Delay가 LCP 시간의 2%로 줄었습니다. 이는 단순한 아키텍처 수정으로 거대한 성능 병목 현상을 어떻게 해결할 수 있는지 보여줍니다. - 사례 2: 실제 환경의
loading="lazy"안티 패턴: 스택 오버플로우(Stack Overflow)의 한 개발자가 빠른 네트워크에도 불구하고 1,430ms의 당혹스러운 Load Delay를 보이는 데스크톱 LCP를 보고했습니다. 원인을 추적한 결과,src속성을 투명한 placeholder SVG로 바꿔 LCP 이미지에 lazy loading을 잘못 적용하는 이미지 최적화 플러그인 때문이었습니다. 확실한 해결책은 LCP 요소에 대해 이 동작을 비활성화하여 조기에 발견하고 즉각적으로(eagerly) 로드되도록 하는 것이었습니다. 이는 서드파티 도구가 어떻게 무심코 심각한 Load Delay를 유발할 수 있는지 잘 보여줍니다. - 사례 3:
fetchpriority성능 향상: 구글 플라이트 사례 연구는 명시적 우선순위 지정의 효과에 대한 명확한 증거를 제공합니다. 페이지의 LCP background image에fetchpriority="high"를 추가하는 것만으로 LCP 점수가 2.6초에서 1.9초로 700ms 향상되었습니다. 이는 리소스를 발견할 수 있는 상황이더라도 브라우저에 리소스의 높은 중요도를 알리는 것이 네트워크 대역폭 경쟁에서 승리하는 데 중요한 단계임을 증명합니다.
Chrome DevTools에서의 네트워크 검사: Ctrl + Shift + I 단축키를 사용하여 Chrome의 개발자 도구를 연 다음 "Network" 탭을 선택하고 페이지를 새로고침하십시오. 로딩 순서를 살펴보십시오. LCP 리소스가 다운로드 대기열의 첫 번째 항목 중 하나여야 합니다. 다른 요소에 뒤쳐져 있다면 Resource Load Delay 문제가 있는 것입니다. 아래는 Resource Load Delay가 최적화되지 않은 사이트의 예입니다.

실제 사용자 모니터링(RUM) 데이터 사용: Real User Monitoring 도구는 종종 LCP attribution 데이터를 기록합니다. RUM을 사용하면 (시간 경과에 따라 또는 페이지별로) LCP 하위 단계의 세부 정보를 시각화할 수 있으므로, 전체 사이트 또는 각 페이지의 LCP 요소에 대한 Load Delay를 명확하게 파악할 수 있습니다. 아래 예시는 글로벌 LCP 세부 정보와 그에 해당하는 Load Delay를 보여줍니다.

Load Delay 개선 방법
Resource Load Delay는 리소스 다운로드 순서와 타이밍이 최적화되지 않았을 때 발생합니다. 본질적으로 이를 수정하는 두 가지 직접적인 방법이 있습니다. LCP 리소스의 우선순위를 높이거나 LCP가 아닌 리소스의 우선순위를 낮추는 것입니다. 몇 가지 일반적인 패턴을 살펴보겠습니다.
LCP 팁: 프리로드 스캐너 이해하기: 최신 브라우저는 HTML을 빠르게 스캔하여 다운로드할 리소스를 대기열에 추가하는 프리로드 스캐너라는 메커니즘을 사용합니다. 리소스를 프리로드 스캐너가 대기열에 추가할 수 없으면, 더 느린 DOM 파서를 기다려야 하므로 지연이 발생합니다. 프리로드 스캐너가 LCP 리소스를 발견할 수 있게 하면 Load Delay를 줄이는 데 큰 차이를 만들 수 있습니다.
1. HTML 구조 최적화
브라우저(또는 프리로드 스캐너)는 HTML을 위에서 아래로 처리하며 리소스가 나타나는 순서대로 대기열에 추가합니다. 즉, LCP 리소스가 HTML에서 더 높은 곳에 나타날수록 대기열에 더 빨리 추가됩니다. 이를 최적화하려면 HTML 상단에서 불필요한 리소스를 제거하거나 지연시키십시오.
- 중요하지 않거나 숨겨진 이미지 지연 로드(Lazy-Load): 사이트 HTML의 맨 상단에 이미지(예: 특정 언어 버전 사이트를 위한 국기 또는 메뉴 이미지)가 배치된 경우가 있습니다. 이러한 이미지는 LCP 요소만큼 중요하지 않습니다. 이 이미지들에 lazy loading을 적용하면 프리로드 스캐너가 건너뛰고 로드 프로세스 중 조금 더 나중에 대기열에 추가됩니다.
- 중요하지 않은 스크립트를 페이지 하단으로 이동: 채팅 위젯과 같이 초기 로드에 전혀 중요하지 않은 스크립트를 페이지 맨 아래로 이동시켜 중요 리소스의 지연을 방지하십시오. 인터넷 역사상 페이지가 보이기도 전에 채팅을 해야 했던 사람은 아무도 없습니다!
2. 배경 이미지 피하기
background image는 프리로드 스캐너에 보이지 않으므로, 항상 훨씬 느린 DOM 파서에 의해 대기열에 추가됩니다. 이러한 지연을 피하려면 object-fit: cover CSS 속성과 결합하여 배경 이미지의 형태를 모방하는 일반 <img> 태그를 사용하십시오. 이렇게 하면 프리로드 스캐너가 이미지를 즉시 감지하고 대기열에 추가할 수 있습니다.
3. Fetch Priority 사용
LCP 요소에 fetchpriority="high" 속성을 추가하여 브라우저에 처음부터 이 리소스의 우선순위를 높여야 한다는 힌트를 제공하십시오. 일반적으로 이미지는 기본적으로 낮거나 중간 우선순위로 로드됩니다. 레이아웃 단계에서 브라우저는 표시되는 요소의 우선순위를 높음으로 업그레이드합니다. fetchpriority="high"를 설정하면 다운로드가 즉시 높은 우선순위로 시작되어 더 빠른 LCP를 보장합니다.
Fetchpriority는 요소의 상대적 우선순위를 설정하기 때문에(이 경우 이미지가 다른 이미지보다 상대적으로 중요함) 일반적으로 프리로드보다 덜 침투적이며 효과가 적습니다. 예를 들어 스타일시트나 비차단(non-blocking) 스크립트보다 우선순위를 높이지는 않기 때문입니다.
<img src="hero-image.jpg" alt="히어로 이미지" fetchpriority="high">4. 프리로드 구현
프리로드는 프리로드 스캐너가 파일을 대기열에 추가하는 순서를 바꿉니다. 페이지의 head에 <link rel="preload"> 태그를 배치하여 브라우저가 LCP 이미지와 같은 중요 리소스를 가능한 한 빨리 가져오도록 지시하십시오. 프리로드는 HTML 후반부에 참조되어 늦게 대기열에 추가되는 리소스를 프리로드하거나, 특정 슬라이더처럼 HTML에 아직 참조되지 않은 리소스를 프리로드하는 데에도 사용할 수 있습니다. 최대의 효과를 위해 프리로드는 페이지의 head 내에서 스타일시트 뒤, 스크립트 앞에 배치하는 것을 권장합니다.
<link rel="preload" as="image" href="hero-image.jpg">5. 스타일 최적화
스타일시트는 일반적으로 LCP 리소스보다 먼저 대기열에 추가되며 그럴 만한 합당한 이유가 있습니다. 스타일시트가 없으면 브라우저는 페이지가 어떻게 보일지 알 수 없어 렌더링 단계를 시작할 수 없습니다. 그러나 과도한 CSS 크기와 너무 많은 스타일시트는 초기 대역폭을 두고 LCP 리소스와 경쟁하게 됩니다.
6. 효율적인 Lazy Loading 구현
loading 속성은 양날의 검이 될 수 있습니다. 오프스크린 이미지에는 loading="lazy"를 적용하되, LCP 리소스에는 loading="eager"를 사용하십시오("eager"가 브라우저 기본값이므로 속성을 생략해도 됩니다).
- LCP 요소에 Eager Load 적용: LCP 요소에 lazy loading을 적용하면 프리로드 스캐너의 대기열에 추가되지 않고 훨씬 나중에 로드되어 성능에 부정적인 영향을 미칩니다.
- Viewport 이미지에 Lazy Loading 적용: 보이는 viewport 안에 있지만 LCP 리소스가 아닌 이미지의 경우,
loading="lazy"를 사용하여 다운로드 대기열에 약간 늦게 추가하십시오. 이는 LCP 리소스와의 대역폭 경쟁을 줄입니다. - 오프스크린 이미지의 Lazy Loading 피하기: 보이는 viewport에 없는 이미지는 다운로드를 전혀 트리거하지 않으므로 대역폭 경쟁을 완전히 제거합니다.
7. 브라우저 캐싱
브라우저 캐싱을 사용하면 사용자의 기기에 로컬로 이미 저장된 리소스에 대한 네트워크 요청을 건너뛸 수 있습니다. 첫 번째 페이지 뷰의 속도를 높여주지는 않지만 후속 페이지 뷰 및 재방문 사용자의 로드 시간을 개선합니다. 브라우저 캐싱이 Resource Load Delay에 도움이 되는 방법은 다음과 같습니다.
- 경쟁 리소스 캐싱: LCP 리소스 자체를 캐싱하는 것도 훌륭한 전략이지만, 브라우저 캐싱은 스크립트, 스타일시트, 이미지처럼 LCP 리소스와 경쟁하거나 지연시킬 수 있는 네트워크 리소스를 저장하여 LCP Resource Load Delay를 개선합니다.
- 서버 부하 감소: 캐싱은 서버로 전송되는 요청 수를 줄여주며, 이를 통해 대역폭을 확보하고 서버 CPU 사이클을 줄여 다른 리소스의 성능을 향상시킬 수 있습니다.
8. Speculation Rules 사용
Speculation Rules를 사용하면 예측된 사용자 이동(navigation)을 기반으로 브라우저가 웹 페이지를 프리페치(prefetch)하거나 사전 렌더링(prerender)할 수 있습니다. 프리페치는 LCP의 하위 단계인 Time to First Byte를 효과적으로 제거하며 Resource Load Delay에는 영향을 미치지 않습니다. 사전 렌더링은 숨겨진 탭에서 다음 페이지를 렌더링하고 모든 페이지 리소스를 다운로드합니다. 이 사전 렌더링된 페이지의 LCP 세부 정보 예시에서 볼 수 있듯이 이는 LCP 요소의 모든 Load Delay를 제거합니다.

9. 클라이언트 사이드 렌더링 피하기
다음 단계: LCP 최적화 계속하기
Resource Load Delay는 네 가지 LCP 단계 중 하나입니다. 발견 대기 시간(discovery latency)을 최소화한 후에는 다음 가이드를 계속 진행하십시오.
- LCP 문제 식별 및 수정: 모든 LCP 문제를 찾고 수정하기 위한 완벽한 진단 방법론입니다.
- LCP 이미지 최적화: 이미지 포맷 선택, 반응형 이미지, 프리로드 및 일반적인 이미지 실수.
- Resource Load Duration: 브라우저가 리소스를 발견한 후 압축, 최신 포맷, CDN 최적화를 통해 다운로드하는 데 걸리는 시간을 줄입니다.
- Element Render Delay: 리소스 다운로드 후 main thread를 정리하여 브라우저가 즉시 페인트할 수 있도록 합니다.
진짜 뭐가 느린지부터.
실제 필드 데이터로 Critical Rendering Path를 뜯어봅니다. Lighthouse 리포트가 아니라 우선순위가 매겨진 수정 목록을 드립니다.
감사 받기