LCP 개선, 어디서부터 손대야 예산을 지킬 수 있나?
결론부터 적는다. LCP 예산은 2.5초를 상한선으로 잡고, 이미지 최적화와 렌더 차단 자원 제거를 먼저 처리한 뒤 코드 스플리팅·지연 로딩을 그다음 순서로 두는 편이 실측 근거와 맞는다. 번들 전체 크기를 줄이는 작업보다 "LCP 경로에 실제로 걸리는 자원"을 먼저 걷어내는 쪽이 체감 개선폭이 크다는 게, 판교에서 몇 번 LCP 회귀 티켓을 처리하며 다시 확인한 순서다.
- LCP 목표선은 2.5초 이내가 "good", 2.5~4.0초는 "needs improvement", 4.0초 초과는 "poor"로 구분된다Google Search Central Core Web Vitals.
- 이미지 최적화(포맷 전환,
fetchpriority, lazy-load 제외)가 즉효성이 큰 축으로 반복 등장한다. - 렌더 차단 자원 제거는 LCP의 "보이는 시점" 자체를 앞당기는 수단이다.
- 코드 스플리팅·지연 로딩은 초기 경로 JS를 줄이는 후순위 수단으로 다뤄진다.
- 회귀 방지는 RUM과 synthetic test를 같이 걸어야 의미가 있다.
LCP 병목, 무엇이 먼저 갈리는 지점인가?
판단이 갈리는 지점은 "히어로 요소가 뭘로 막혀 있느냐"다. 같은 LCP 4초짜리 페이지라도 원인은 셋 중 하나로 갈린다 — 이미지가 늦게 뜨는 경우, 렌더 차단 스크립트/CSS가 앞을 막는 경우, 메인 스레드가 JS 파싱·실행에 점유된 경우. 이 셋을 구분하지 않고 "일단 번들부터 줄이자"로 들어가면 며칠짜리 리팩터링을 하고도 LCP가 그대로인 경우를 겪게 된다.
실무에서는 Lighthouse나 PageSpeed Insights의 LCP 요소 하이라이트로 원인을 먼저 특정한다. 히어로 이미지가 LCP 요소로 잡히면 이미지 축, <head>의 render-blocking 리소스 경고가 뜨면 렌더 차단 축, TBT(Total Blocking Time)가 같이 높으면 JS 실행 축이다. 공개 사례들에서도 우선순위는 이미지 최적화와 렌더 차단 자원 제거가 먼저이고, 코드 스플리팅은 그다음으로 다뤄진다. 즉 "무엇을 먼저 볼까"의 답은 감이 아니라 LCP 요소가 무엇인지부터 확인하는 데서 나온다.
히어로 이미지 최적화, WebP·fetchpriority로 충분한가?
충분하다고 단정하기는 어렵지만, 공개 사례에서 가장 자주 등장하는 조합인 것은 맞다. 확인된 사례 중 하나는 above-the-fold 이미지를 WebP로 전환하고, 히어로 이미지에 fetchpriority="high"를 부여하고, analytics 스크립트를 defer로 옮기는 세 가지를 3주간 적용해 LCP를 5.2초에서 1.8초로 줄였다고 보고한다. 다만 이 수치는 개별 블로그 사례라 재현 가능한 원자료(로그·실험 설계)까지 공개되지 않았고, 보편적 효과 크기로 일반화하기는 조심스럽다.
실무에서 체크할 지점은 세 가지다. 첫째, 히어로 이미지에 width/height를 명시해 레이아웃 시프트와 별개로 브라우저가 미리 공간을 잡게 한다. 둘째, LCP 요소인 이미지는 loading="lazy"에서 제외해야 한다 — lazy-load가 걸리면 뷰포트 안에 있어도 우선순위가 낮아진다. 셋째, fetchpriority="high"는 히어로 이미지 하나에만 주는 게 원칙이다. 여러 개에 걸면 우선순위 신호 자체가 무의미해진다.
렌더 차단 스크립트를 defer로 미루면 LCP가 당겨지나?
당겨질 가능성이 높은 축이긴 하지만, 어떤 스크립트를 미루느냐에 따라 갈린다. 공개 사례에서는 비핵심 third-party 스크립트(주로 analytics/tracking)를 <head>에서 빼고 deferred로 옮긴 것이 개선 요소로 적시된다. 반대로 히어로 이미지 렌더링에 직접 관여하는 CSS나 폰트 로딩까지 무작정 지연시키면 오히려 LCP가 늦어지거나 텍스트가 깜빡이는 FOIT/FOUC 문제가 새로 생긴다.
렌더 차단 자원 제거는 LCP의 "보이는 시점"을 직접 당기는 수단으로 다뤄지기 때문에, 우선순위상 이미지 최적화와 나란히 앞자리에 둔다. 실무적으로는 <head> 안의 스크립트 태그를 하나씩 보면서 "이게 LCP 요소를 그리는 데 필요한가"를 기준으로 defer/async 여부를 정하는 편이 안전하다. 필요 없는 스크립트를 무조건 다 미루는 것보다, LCP 경로에 있는지 없는지를 먼저 확인하는 쪽이 회귀를 덜 만든다.
코드 스플리팅과 지연 로딩, LCP엔 얼마나 기여하나?
기여는 하지만 이미지·렌더차단 축보다 후순위로 다뤄진다는 게 공개 자료들의 공통된 결이다. 번들 예산은 "전체 JS 크기"보다 "초기 경로 JS"에 두는 게 실측에 더 맞는다. 코드 스플리팅으로 초기 로드 시 실행되는 JS를 줄이면 메인 스레드 점유가 줄어 LCP 요소가 더 빨리 페인트될 여지가 생기지만, 이미 이미지·렌더차단 문제가 해결되지 않은 상태라면 코드 스플리팅만으로는 개선폭이 작게 나온다.
이때 숫자는 보통 LCP 자체보다 세션 지속 시간 같은 후행 지표로 제시된다. Tokopedia 사례에서는 LCP를 55% 개선한 결과 평균 세션 지속 시간이 23% 개선됐다고 보고된다. 코드 스플리팅이 이 개선에서 몇 퍼센트를 차지했는지까지는 공개되지 않았지만, 이미지·렌더차단 개선과 함께 갔을 때 후행 지표가 움직였다는 점은 참고할 만하다.
이 판단을 뒷받침하는 실측 근거는 무엇인가?
가장 신뢰도가 높은 축은 공식 사례 두 건이다. Vodafone Italy는 LCP를 31% 개선했고 그 결과 매출이 8% 증가했다고 web.dev의 Core Web Vitals 비즈니스 임팩트 사례에 소개돼 있다. Tokopedia는 LCP를 55% 개선했고 평균 세션 지속 시간이 23% 개선됐다고 같은 시리즈에 실려 있다. 두 사례 모두 이미지 최적화와 렌더 차단 자원 제거를 개선 축의 앞자리에 두었다는 점에서 이 글의 우선순위 판단과 결이 같다.
기준선 자체는 Google Search Central과 2025년 HTTP Archive Web Almanac이 같은 임계값을 쓴다 — LCP 2.5초 이하 good, 2.5~4.0초 needs improvement, 4.0초 초과 poor. 2026년 기준으로도 이 임계값은 바뀌지 않았고, RUM(CrUX)과 synthetic test(Lighthouse/PageSpeed Insights)를 병행해서 보라는 안내도 유지되고 있다. 다만 "이미지 최적화가 몇 퍼센트를 보장한다" 같은 일반화 수치는 이번에 확인된 자료 안에서는 근거가 약해, 개별 사례의 결과값으로만 참고하는 편이 안전하다.
이미지·JS 최적화에서 자주 놓치는 함정은?
가장 흔한 함정은 "LCP 요소가 아닌 자원을 먼저 최적화하는 것"이다. 이미지 전체를 WebP로 바꾸고 lazy-load를 걸었는데 정작 LCP 요소인 히어로 이미지에 lazy-load가 걸려 있어서 개선이 안 되는 경우가 실제로 있다. 또 하나는 코드 스플리팅을 먼저 하고 이미지·렌더차단 문제를 나중에 보는 순서 역전이다 — 이 경우 스플리팅 작업량 대비 LCP 개선폭이 작게 나와서 "효과가 없다"는 잘못된 결론으로 이어지기 쉽다.
RUM과 synthetic test 값이 다르게 나오는 것도 흔한 함정이다. Lighthouse 랩 데이터는 특정 네트워크·CPU 조건을 시뮬레이션한 값이라, 실제 사용자 분포(저사양 기기, 느린 네트워크)를 반영한 CrUX 데이터와 차이가 날 수 있다. 배포 전후 비교를 CI에 걸어두더라도, 실사용자 지표가 따라오는지는 별도로 확인해야 한다. 마지막으로, 개인/기관 블로그 사례의 수치(예: 3주 만에 5.2초→1.8초)는 참고 사례 수준으로만 인용하고, 그대로 목표치로 삼지 않는 편이 낫다.
결국 어떤 상황에 무엇을 먼저 고르나?
LCP 요소가 이미지라면 포맷 전환·fetchpriority·lazy-load 제외를 먼저, 렌더 차단 리소스가 걸려 있다면 그 제거를 나란히, 메인 스레드 점유가 원인이면 코드 스플리팅을 그다음에 배치하는 것이 실측 근거에 맞는 순서다.
- LCP 요소부터 특정하라: Lighthouse/PageSpeed로 무엇이 막고 있는지 먼저 본다.
- 이미지 축: WebP/AVIF 전환,
width/height명시, 히어로 이미지 lazy-load 제외,fetchpriority="high"는 하나에만. - 렌더 차단 축: 비핵심 third-party 스크립트를 head에서 빼고 defer, LCP에 필요한 CSS/폰트는 그대로 둔다.
- JS 축: 초기 경로 JS 크기를 예산으로 관리하고, 코드 스플리팅은 이미지·렌더차단 개선 이후에 배치한다.
- 회귀 방지: RUM(CrUX)과 synthetic test를 병행하고, 2.5초를 CI 임계값으로 걸어둔다.
핵심 정리
- LCP 예산은 2.5초 이하를 기준선으로 두고, 이미지 최적화·렌더 차단 자원 제거를 코드 스플리팅보다 먼저 처리한다.
- Vodafone(LCP 31%↓, 매출 8%↑), Tokopedia(LCP 55%↓, 세션시간 23%↑) 사례가 이 우선순위를 뒷받침하지만, 효과 크기를 일반화하지는 않는다.
- 히어로 이미지는 lazy-load 제외,
fetchpriority="high"는 하나에만, width/height 명시가 실무 체크리스트다. - 렌더 차단 자원은 LCP 요소 렌더링에 필요한지 여부로 defer 대상을 가려야 회귀를 줄인다.
- 회귀 방지는 RUM과 synthetic test를 병행하고, 2.5초를 CI/CD 임계값으로 걸어두는 방식이 적합하다.