본문 바로가기
개발 일지

[ 개선 ] Lighthouse 경고 하나씩 없애보기 1: LCP Request Discovery -이미지 최적화하기

by CODESIGN 2026. 5. 23.
반응형

Lighthouse를 돌렸을 때 처음 마주한 문제는 Performance 점수였다.  
특히 첫 화면 상단에 있는 로고 이미지가 LCP 관련 경고에 계속 잡히고 있었다.

이번 글은 로고 하나를 최적화하면서 Lighthouse 경고가 어떻게 바뀌었고, 어떤 순서로 해결했는지 정리한 기록이다.

 

첫 번째 경고: LCP Request Discovery



처음 Lighthouse에서 나온 경고는 다음과 같았다.

LCP request discovery

세부 항목은 이런 내용이었다.

fetchpriority=high should be applied
Request is discoverable in initial document
lazy load not applied

즉, Lighthouse는 이렇게 말하고 있었다.

> LCP로 잡힌 이미지가 HTML에서 바로 발견되지 않는다.  
> 더 빨리 발견되게 만들고, 우선순위도 높여라.

문제의 대상은 상단 로고 이미지였다.

기존에는 React 코드에서 이미지를 import 해서 사용하고 있었다.

import logo from '../../assets/logo6.jpeg'

<img src={logo} alt="Koti Logo" />


이 방식은 일반 이미지에는 괜찮지만, LCP 이미지에는 불리할 수 있다.

브라우저가 처음 받는 것은 `index.html`이다.  
그런데 위 이미지는 HTML에 직접 드러나 있지 않고, JavaScript 번들이 로드되고 React가 실행된 뒤에야 `<img>`로 렌더링된다.

흐름은 대략 이렇다.

HTML 다운로드
→ JS 번들 다운로드
→ React 실행
→ img 태그 생성
→ 이미지 요청 시작

 

LCP 이미지라면 이 요청 시점이 너무 늦다.



첫 번째 수정: preload와 fetchPriority 적용


먼저 로고 이미지를 브라우저가 HTML 단계에서 바로 발견할 수 있도록 `public` 경로로 옮겼다.

public/koti-logo.png


그리고 `index.html`에 preload를 추가했다.

<link rel="preload" as="image" href="/koti-logo.png" fetchpriority="high" />


React 코드에서는 이미지 경로를 고정 URL로 바꾸고, `fetchPriority="high"`를 추가했다.

const logo = '/koti-logo.png'

<img
  src={logo}
  alt="Koti Logo"
  width="400"
  height="67"
  fetchPriority="high"
/>


관리자 메뉴 쪽 로고도 동일하게 변경했다.

const logo = '/koti-logo.png'

<img
  src={logo}
  alt="Koti Logo"
  width="390"
  height="66"
  fetchPriority="high"
/>


이렇게 하면 브라우저는 React가 실행되기 전에 `index.html`을 파싱 하는 단계에서 이미 로고 이미지를 알 수 있다.

정리하면 첫 번째 수정은 다음과 같다.

React import 이미지
→ public 고정 경로 이미지
→ index.html preload
→ img fetchPriority="high"
→ width / height 명시



두 번째 경고: 이미지 크기가 너무 큼




첫 번째 수정을 하고 다시 Lighthouse를 돌렸더니 경고가 바뀌었다.

Improve image delivery
Est savings of 290 KiB


이번에는 이미지가 늦게 발견되는 문제가 아니었다.  
이제는 이미지 파일 자체가 너무 크다는 문제였다.

Lighthouse는 이렇게 알려줬다.

This image file is larger than it needs to be (4184x705)
for its displayed dimensions (800x135).


실제 파일을 확인해보니 다음과 같았다.

public/koti-logo.png
4184 x 705
약 301 KB


하지만 화면에서 필요한 크기는 훨씬 작았다.  
로고는 코드상 약 `400px` 너비로 표시되고 있었다.

width="400"
height="67"


Retina 디스플레이까지 고려해도 2배 크기인 `800 x 135`면 충분했다.



두 번째 수정: 이미지 리사이즈



그래서 로고 이미지를 `800 x 135`로 리사이즈했다.

Mac에서는 `sips` 명령어를 사용할 수 있다.

sips -z 135 800 public/koti-logo.png --out public/koti-logo.png


수정 전후는 다음과 같았다.

 

수정 전
4184 x 705
약 301 KB

수정 후
800 x 135
약 55 KB


이 단계에서 약 `246 KB` 정도 줄었다.

이제 더 이상 400px로 표시할 이미지를 위해 4184px짜리 원본을 내려주지 않게 됐다.

 

세 번째 경고: 최신 이미지 포맷 사용


리사이즈 후 다시 Lighthouse를 돌렸더니 경고가 또 바뀌었다.

Improve image delivery
Est savings of 38 KiB

이번에는 예상 절감량이 크게 줄었다.  
처음에는 290KiB였는데, 리사이즈 후에는 38KiB 정도만 남았다.

Lighthouse 메시지도 달라졌다.

Using a modern image format (WebP, AVIF) or increasing the image compression could improve this image's download size.



즉, 이제 문제는 해상도가 아니라 이미지 포맷이었다.

현재 파일은 PNG였다.

public/koti-logo.png
800 x 135
약 55 KB

PNG는 로고처럼 선명한 이미지에 자주 쓰이지만, 경우에 따라 WebP가 더 작은 파일 크기를 만들 수 있다.

 

세 번째 수정: WebP로 변환



그래서 같은 이미지를 WebP로 변환했다.

변환 후 파일은 다음과 같았다.

public/koti-logo.webp
800 x 135
약 21 KB

PNG와 비교하면 이렇다.

PNG
55 KB

WebP
21 KB

약 `34 KB` 정도 더 줄었다.

그리고 `index.html`의 preload 대상도 WebP로 바꿨다.

<link
  rel="preload"
  as="image"
  href="/koti-logo.webp"
  type="image/webp"
  fetchpriority="high"
/>



React 코드의 로고 경로도 WebP로 변경했다.

const logo = '/koti-logo.webp'

<img
  src={logo}
  alt="Koti Logo"
  width="400"
  height="67"
  fetchPriority="high"
/>



관리자 메뉴도 동일하게 변경했다.

const logo = '/koti-logo.webp'

<img
  src={logo}
  alt="Koti Logo"
  width="390"
  height="66"
  fetchPriority="high"
/>



여기서 중요한 점은 preload와 실제 `img src`를 같은 파일로 맞췄다는 것이다.

만약 preload는 `/koti-logo.webp`로 하고, 실제 이미지는 `/koti-logo.png`로 렌더링하면 브라우저가 이미지를 중복 다운로드할 수 있다.

그래서 반드시 이렇게 맞춰야 한다.

preload href = 실제 img src


최종 결과



로고 최적화 과정은 총 세 단계였다.

1단계
LCP 이미지가 HTML에서 늦게 발견됨
→ public 경로로 이동
→ preload 추가
→ fetchPriority="high" 추가

2단계
이미지 원본 해상도가 너무 큼
→ 4184 x 705 이미지를 800 x 135로 리사이즈
→ 301 KB에서 55 KB로 감소

3단계
PNG 포맷이 여전히 무거움
→ WebP로 변환
→ 55 KB에서 21 KB로 감소


최종적으로 로고 파일은 다음처럼 줄었다.

초기 원본
4184 x 705
약 301 KB

리사이즈 후 PNG
800 x 135
약 55 KB

WebP 변환 후
800 x 135
약 21 KB


결과적으로 Lighthouse에서 로고 관련 경고가 제거됐다.

마무리


LCP 이미지는 성능 점수에 큰 영향을 준다.

특히 첫 화면에 보이는 로고, 히어로 이미지, 대표 썸네일 같은 이미지는 다음을 꼭 확인하는 게 좋다.

1. HTML에서 빨리 발견되는가?
2. lazy loading이 걸려 있지는 않은가?
3. fetchPriority가 필요한 이미지인가?
4. 실제 표시 크기에 비해 원본이 너무 크지 않은가?
5. WebP/AVIF 같은 최신 포맷을 쓸 수 있는가?
6. width와 height가 명시되어 있는가?


이번 로고 최적화는 작은 작업처럼 보이지만, Lighthouse 경고를 실제로 하나씩 제거해 가며 성능 개선의 흐름을 잡기에 좋은 예시였다.

다음에는 이미지가 아니라, Vite 빌드에서 계속 남아 있는 큰 JavaScript 번들 경고를 살펴볼 예정이다.

 

 

반응형

댓글