React Native 에서 이미지 최적화 (3. 이미지 Preload시 주의사항)

eeennsu·2026년 8월 26일

React Native

목록 보기
87/96

1. Preload의 핵심 원칙

프리로드하는 URL은 컴포넌트가 실제로 렌더링할 URL과 글자 단위까지 동일해야 한다.
FastImage는 URL(+헤더)를 캐시 키로 쓰기 때문에, URL이 조금이라도 다르면 다른 캐시로 취급되어 프리로드가 무효가 된다.

// 컴포넌트가 이걸 렌더링한다면
<FastImage source={{ uri: 'https://cdn.example.com/img.jpg?w=300' }} />

// 프리로드도 정확히 같은 URL로 해야 한다
FastImage.preload([{ uri: 'https://cdn.example.com/img.jpg?w=300' }]);


2. 리사이징된 이미지는 리사이징된 URL로 프리로드한다

서버/CDN에서 리사이징한 이미지를 표시한다면, 리사이징된 URL로 프리로드해야 한다.

// ❌ 잘못된 예 — 원본을 프리로드, 화면엔 리사이즈본을 표시
FastImage.preload([{ uri: 'https://cdn.example.com/img.jpg' }]);
//... 마운트 시
<FastImage source={{ uri: 'https://cdn.example.com/img.jpg?w=300&h=300' }} />
// → 캐시 키가 다름 → 마운트 시 재다운로드 → 프리로드 의미 없음

// ✅ 올바른 예 — 표시할 URL 그대로 프리로드
const displayUrl = 'https://cdn.example.com/img.jpg?w=300&h=300';
FastImage.preload([{ uri: displayUrl }]);
//... 마운트 시
<FastImage source={{ uri: displayUrl }} />

표시용 URL을 만드는 함수를 하나 만들어 두고, 프리로드와 렌더링 양쪽에서 같은 함수를 호출하면 불일치를 원천 차단할 수 있다.

const buildImageUrl = (id: string, w: number, h: number) =>
  `https://cdn.example.com/${id}.jpg?w=${w}&h=${h}`;

const url = buildImageUrl('img', 300, 300);
FastImage.preload([{ uri: url }]); // 프리로드
<FastImage source={{ uri: url }} />; // 렌더링

3) resizeMode와 "실제 리사이징"을 혼동하지 않는다

구분의미캐시 키에 영향
서버/CDN 리사이징URL이 다름, 받는 바이트가 다름 (?w=300 등)영향 있음 → 표시 URL로 프리로드 필요
resizeMode (cover/contain/...)받아온 이미지를 화면에 맞추는 표시 방식영향 없음 → 같은 URL이면 같은 캐시

즉 resizeMode만 다르고 URL이 같으면 프리로드는 그대로 유효하다. 신경 쓸 건 "URL이 달라지는 리사이징"뿐이다.


4) URL이 미세하게 달라지는 케이스 주의 (캐시 미스 유발)

같은 이미지인데 캐시 미스가 나는 흔한 원인들:

  • 쿼리 파라미터 순서가 다름 (?w=300&h=300 vs ?h=300&w=300)
  • 불필요한 파라미터가 붙거나 빠짐 (&t=... 타임스탬프, 트래킹 파라미터 등)
  • 프로토콜/도메인 차이 (http vs https, cdn. 유무)
  • 대소문자/인코딩 차이 (%2F vs /)

→ URL을 정규화(normalize) 해서 프리로드와 렌더링에 동일하게 쓰는 것이 안전하다.


5) 인증 헤더 / 서명(presigned) URL 주의

  • 헤더가 필요한 이미지는 프리로드 시에도 같은 headers를 넘겨야 한다.

    FastImage.preload([
      { uri: url, headers: { Authorization: `Bearer ${token}` } },
    ]);
  • 서명/만료되는 URL(presigned) 은 특히 주의한다.

    • 프리로드할 때 생성한 URL과 렌더링할 때 생성한 URL의 서명 쿼리(X-Amz-Signature, 토큰 등)가 다르면 서로 다른 캐시 키가 된다 → 캐시 미스.
    • 프리로드 후 마운트까지 시간이 지나 토큰이 만료되면 다운로드 자체가 실패할 수 있다.
    • 대응: 같은 URL 문자열을 재사용하거나, 만료 시간을 충분히 길게 잡거나, (포크가 지원한다면) 안정적인 cacheKey를 사용한다.

6) 프리로드 양과 타이밍

  • 곧 화면에 보일 것만 선별적으로 프리로드한다. 리스트 전체를 한 번에 프리로드하면 대역폭·디스크·메모리 낭비다.
  • 다음 화면 진입 직전, 또는 리스트에서 곧 보일 다음 페이지 정도만 미리 받는 패턴이 적절하다.
  • 프리로드는 fire-and-forget 으로 두되, 결과를 기다려 UI를 막지 않는다.

7) 프리로드가 보장하는 범위

  • 프리로드는 보통 네트워크 다운로드 + 디스크 캐시 저장까지를 보장한다.
  • 디코딩(decode)·디스플레이 준비까지 미리 끝내주는 것은 아니다. 따라서 마운트 시점에 디코딩 비용은 남을 수 있다. "프리로드 = 화면에 즉시 픽셀이 뜬다"가 아니라 "네트워크 왕복을 없애준다"로 이해한다.

정리

이미지 URL에 리사이징·최적화 파라미터를 붙이는 것은 단순한 편의 기능이 아니라, 네트워크·메모리·렌더링 성능을 한 번에 개선하는 핵심 최적화 기법이다. 요점은 다음과 같다.

  • 표시 크기에 맞춰 w를 지정해 불필요하게 큰 이미지를 받지 않는다.
  • React Native에서는 PixelRatio를 반영하되, 과도한 요청을 막기 위해 DPR 상한을 두는 것을 고려한다.
  • q=75~85로 화질과 용량의 균형을 맞춘다.
  • f=webp(또는 상황에 따라 avif)로 포맷을 최적화한다.
  • 파라미터 조합을 일정하게 유지해 CDN 캐시 적중률을 높인다.

특히 메모리에 민감한 모바일 환경에서는, 비트맵 디코딩 메모리가 파일 용량이 아니라 픽셀 수에 비례한다는 점 때문에 리사이징의 효과가 웹보다 훨씬 크게 나타난다.

profile
이력서 https://resume.eunsu.pro

0개의 댓글