[Front] 프론트 성능 최적화 - 이미지 최적화

devicii·2024년 12월 30일
0

Front

목록 보기
2/8
post-thumbnail

0. 글을 작성하게 된 계기

현재 배포한 사이트에서 성능을 '느린' 네트워크 환경에서 체크했을 경우에 LCP(Largest Contentful Paint) 수치가 높았다.
disable cache, slow 4g, 모바일 환경, 시크릿 모드에서 측정했을 시에 LCP가 10초 이상이 나오는 상황이다. Google에서 권장하는 LCP 기준이 2.5초 이하인 것을 감안하면, 이는 상당히 높아서 개선해야 했다.

0-1. 성능 측정


테스트 환경
- mobile 환경
- slow 4G 네트워크 에뮬레이션
- 캐시 비활성화 상태
- 시크릿 모드 

**측정 결과** (5회 연속 측정)

| 측정 지표 | 1회차 | 2회차 | 3회차 | 4회차 | 5회차 | 평균 |
|---------|-------|-------|-------|-------|-------|-----|
| Performance | 58  | 59 | 59 | 58 | 59 | 58 |
| Accessibility | 86 | 86 | 86 | 86 | 86 | 86 |
| Best Practices | 96 | 96 | 96 | 96 | 96 | 96 |
| SEO | 92 | 92 | 92 | 92 | 92 | 92 |

개선 전 스크린샷

1. LCP란?

Largest Contentful Paint(LCP)는 Core Web Vitals의 지표 중 하나이다. 뷰포트에서 가장 큰 콘텐츠 엘리먼트가 나타날 때의 시간을 측정한다. 페이지의 주요 내용이 화면에 렌더링이 완료되는 시기를 결정하는데 사용된다.

1-1. LCP에 영향을 미치는 요소들

  • 대형 이미지
  • 비디오 썸네일
  • 큰 텍스트 블록
  • 백그라운드 이미지

1-2. Google에서 제시하는 LCP 기준

  • 좋음: 2.5초 이하
  • 개선 필요: 2.5초 ~ 4초
  • 나쁨: 4초 초과

2. LCP를 최적화 하는 방법

Next.js를 사용하는 경우, Image 컴포넌트를 활용하면 이미지 관련 최적화를 간단히 구현할 수 있다.
이미지를 최적화하는 주요 방법은 아래와 같은 것이 있다.

  1. Lazy loading
  2. 이미지 사이즈 최적화
  3. CLS(Cumulative Layout Shift) 방지

MDN LCP

3. Next/Image로 LCP 개선하기

3-1. Image 컴포넌트가 제공하는 것
Next.js에서 제공하는 Image 컴포넌트는 디바이스 크기에 따라 최신 이미지 포맷(WebP, AVIF)으로 자동 변환된다.
WebP와 AVIF는 기존 jpg와 png의 단점을 보완하기 위해 구글에서 개발한 포맷으로, 브라우저 지원 범위를 고려하는 것이 좋다.

이미지 포맷 선택


// 이전 코드
<Image
   src={image.url ?? DEFAULT_IMAGES.THUMBNAIL}
   alt="Plogging eventDetail main image"
   width={1920}
   height={1080}
   quality={100}
   className="h-auto w-full rounded-lg"
/>
  

priority, quality, placeholder, blurDataURL 속성을 추가했다.

3-2. Next/Image 속성 상세 설명

priority

  • LCP 대상이 되는 이미지에 사용하는 속성
  • 페이지 로드 시 최우선으로 로딩
  • hero 이미지나 배너 이미지처럼 중요한 이미지에 사용 권장

quality

  • 이미지 품질을 1-100 사이로 설정
  • 기본값은 75
  • 높을수록 파일 크기가 커지므로 적절한 밸런스 필요

placeholder

  • 이미지 로딩 중 표시할 임시 이미지 설정
  • "blur" 옵션 사용 시 blurDataURL 필수

blurDataURL

  • placeholder가 "blur"일 때 사용할 base64 인코딩된 이미지 URL
  • 매우 작은 크기(10px)의 흐린 이미지 사용 권장

base64로 blurDataURL 처리하는 방법

     
// 수정된 코드
<Image
   src={image.url ?? DEFAULT_IMAGES.THUMBNAIL}
   alt="Plogging eventDetail main image"
   width={1920}
   height={1080}
   priority // 우선 로딩
   quality={75} // 품질 조정
   placeholder="blur" // 로딩 중 블러 효과
   blurDataURL={BLUR_IMAGES.THUMBNAIL} // 블러 데이터
   className="h-auto w-full rounded-lg"
/>

개선 이후


4. 성능 개선 결과 분석

개선 전후 비교

  • LCP: 10초 이상 → 1.8초 (약 82% 개선)
  • Performance 점수: 50점 → 79점 (약 30% 증가)

주요 개선 포인트
1. 이미지 품질 최적화 (quality: 100 → 75)
2. priority 속성을 통한 로딩 우선순위 조정
3. 로딩 중 사용자 경험 개선 (blur 효과)

추가 개선 가능 사항

  • 이미지 캐싱 전략 수립 (이건 리액트 쿼리를 활용해 추가편을 작성할 생각이다.
  • 반응형 이미지 사이즈 최적화

5. 결론

Next/Image 컴포넌트를 활용한 이미지 최적화를 통해 LCP를 크게 개선할 수 있었다.

하지만 여전히 개선의 여지가 많고, 다음과 같은 개선 사항이 있다.

  • 이미지 캐싱 전략 개선
  • CDN 도입 검토
  • 추가적인 이미지 최적화 기법 적용

웹 성능 최적화는 한 번에 완성되는 것이 아니라 지속적인 모니터링 및 개선이 필요한 과정임을 배웠다.

참고

https://ui.toast.com/posts/ko_202012101720
https://nextjs.org/docs/pages/api-reference/components/image

profile
흘러가는대로 사는

0개의 댓글