Skip to content

피드 이미지 로딩 최적화 및 CLS 완화

heeyongKim edited this page Feb 28, 2026 · 21 revisions

피드 이미지 로딩 최적화 및 CLS 완화

  • PR: PR
  • 적용 대상
    • 피드 메인 페이지 (Feed.tsx)
    • 내 띱 목록 컴포넌트 (FollowerList.tsx)

📄 개요

본 문서는 피드 탭 초기 진입 시 발생하던 피드 글 이미지의 로딩 지연 체감 및 레이아웃 시프트(CLS) 문제의 원인과 개선 과정을 정리합니다.


📑 목차

  1. 문제 배경 및 발생 원인
  2. 해결 전략
  3. 기대효과
  4. 결과

1. 문제 배경 및 발생 원인

피드 탭 초기 진입(+ 무한스크롤) 시 다음과 같은 현상이 발생했습니다.

  • FollowList가 Feed 본문보다 늦게 렌더링되며 화면이 아래로 밀림
  • FollowList와 Feed 스켈레톤 전환 타이밍이 서로 다름
  • 피드 내 미리보기 이미지가 동시에 다수 로딩되며 체감 지연 발생
  • 상단 고정 헤더 기준 패딩 불일치로 CLS 발생

발생원인은 아래와 같습니다.

1.1 CLS 원인

  • FollowList가 TotalFeed 내부에 포함되어 있어 렌더 제어가 어려움
  • Feed와 FollowList가 각각 독립적으로 로딩 상태를 관리
  • 초기 렌더 타이밍이 분리되어 UX 일관성 저하

2.2 이미지 로딩 지연 체감 원인

  • 미리보기 이미지를 제한 없이 렌더
  • lazy loading 미적용

2. 해결 전략

2.1 구조 개선

  • FollowList 렌더 위치 변경
  • TotalFeed 내부에서 분리
  • Feed.tsx에서 직접 렌더하도록 구조 변경

→ 상위 레벨에서 로딩 상태를 통합 관리 가능하도록 개선

2.2 스켈레톤 타이밍 동기화

  • Feed 초기 로딩 조건에 FollowList 로딩 상태 포함
  • FollowList 데이터 조회에 최소 로딩 시간 500ms 적용
  • FollowList와 Post 스켈레톤 전환 시점 통일

2.3 피드 이미지 로딩 최적화

  • 피드 카드(PostBody)에서 미리보기 이미지를 즉시 로딩하지 않고, 뷰포트 근처에 도달했을 때만 실제 이미지 URL을 주입하여 네트워크 요청을 발생시키는 IntersectionObserver 기반 Lazy Loading 구조를 적용

  • 왜 이 방식인가?

    • 현재 화면의 주요 병목은 컴포넌트 코드 번들보다 이미지 리소스 요청/디코딩 비용에 가까움
    • 따라서 React.lazy(코드 스플리팅)보다 이미지 lazy loading이 효과적인 개선
  • PostBody.tsx

    • 피드 미리보기 이미지 렌더링을 LazyImage 컴포넌트로 교체
    • 미리보기 이미지는 최대 3장만 노출하도록 유지 (slice(0, 3))
  • LazyImage

    • IntersectionObserver로 뷰포트 진입 시점에 실제 이미지 로드
    • 로딩 완료 시 blur -> 선명, opacity, scale 전환으로 부드러운 표시 효과 적용
    • loading="lazy", decoding="async", fetchPriority="low" 설정 유지

3. 기대효과

🎯 UX 개선

  • FollowList의 늦은 등장으로 인한 화면 밀림 현상 완화
  • 스켈레톤 표시 타이밍 일관성 확보
  • 초기 진입 시 화면 안정성 향상

⚡ 성능 개선

  • 초기 진입 시 불필요한 이미지 요청 감소
  • 스크롤 시점 기준으로 필요한 이미지부터 로드되어 체감 성능 개선
  • 이미지 로딩 중 시각적 공백 감소(blur/fade 전환)

4. 결과

4.1 CLS 개선

Before

default.mov

After

default.mov

4.2 이미지 로딩 지연 개선

Before

Lazy.Loading.-1.mov
  • 아래쪽(아직 안 보이는 게시글)의 이미지 요청이 한번에 일어남

After

Lazy.Loading.-1.mov
  • 스크롤을 내릴 때마다 새 이미지들이 그때그때 추가로 요청되는 것을 확인할 수 있음

Clone this wiki locally