이미지의 디코딩이란?

eeennsu·2026년 7월 5일

React Native

목록 보기
61/90

개요

RN에서 이미지 캐싱을 다루다 보면 "디코딩"이라는 단어를 계속 만나게 된다. "메모리 캐시를 비우면 다시 디코딩해서 깜빡인다", "큰 이미지 여러 장을 동시에 디코딩하면 프레임이 튄다" 같은 문장들이다.

이 디코딩이 대체 무슨 작업이고, 왜 비용이 크며, 왜 메모리 캐시와 디스크 캐시를 가르는 기준이 되는지를 정리해보자. 이걸 이해하면 앞선 캐시 타이밍 얘기가 훨씬 명확해진다.



1. 디코딩이란 무엇인가

디코딩은 압축된 이미지 파일을 화면에 그릴 수 있는 픽셀 배열(비트맵)로 푸는 작업이다.

JPEG, PNG, WebP 같은 이미지 파일은 디스크나 네트워크에 압축된 상태로 존재한다. JPEG은 DCT 기반 손실 압축, PNG는 무손실 압축 같은 방식으로 용량을 줄여놓은 바이트 뭉치다. 이 상태로는 화면에 그릴 수 없다.

화면(GPU)이 실제로 픽셀을 찍으려면 각 픽셀의 색상값(RGBA)이 순서대로 나열된 raw 배열, 즉 비트맵(bitmap)이 필요하다. 압축된 파일 바이트를 풀어서 이 픽셀 단위 비트맵으로 바꾸는 CPU 연산이 바로 디코딩이다.

[ JPEG/PNG 파일 ]  ──(디코딩)──▶  [ 픽셀 비트맵(RGBA) ]  ──▶  화면에 렌더
   압축된 바이트                    RAM 위의 raw 배열


2. 왜 비싼 작업인가

1) 메모리 용량이 급증한다

디코딩의 가장 큰 특징은 용량이 확 튄다는 점이다. 4000×3000 이미지를 예로 들어보자.

상태크기비고
디스크의 JPEG 파일약 2MB압축된 상태
디코딩된 비트맵4000 × 3000 × 4B = 약 48MBRAM 점유

같은 이미지인데 메모리에 올라간 순간 20배 이상 커진다. 픽셀당 4바이트(R·G·B·A 각 1바이트)가 곧이곧대로 자리를 차지하기 때문이다. 이미지가 많은 화면에서 OOM(메모리 부족 강제 종료)이 터지는 근본 원인이 바로 이 디코딩된 비트맵의 크기다.


2) CPU 시간을 먹는다

압축 해제는 공짜가 아니다. 픽셀 수만큼의 연산이 필요하므로, 큰 이미지 수십 장을 동시에 디코딩하면 그 순간 CPU가 몰리면서 프레임이 튀거나(jank) 스크롤이 버벅인다. 특히 메인 스레드에서 디코딩이 일어나면 UI가 그대로 멈춘다.

FastImage가 내부적으로 쓰는 SDWebImage(iOS)·Glide(Android)는 이 디코딩을 백그라운드 스레드에서 처리하고, 다운샘플링(화면에 필요한 크기만큼만 디코딩)으로 비용을 줄이는 등의 최적화를 갖고 있다. 그래도 디코딩 자체가 사라지는 건 아니다.



3. 메모리 캐시 vs 디스크 캐시가 갈리는 지점

디코딩을 이해하면 두 캐시의 차이가 자연스럽게 설명된다. 각 캐시가 "무엇을" 들고 있느냐가 핵심이다.

캐시저장하는 것다시 보여줄 때
메모리 캐시디코딩이 끝난 비트맵바로 화면에 붙임 (즉시)
디스크 캐시압축된 원본 파일읽어서 다시 디코딩 필요

메모리 캐시는 이미 압축을 다 풀어놓은 완성품(비트맵)을 들고 있으므로 꺼내서 바로 그린다. 반면 디스크 캐시는 압축된 파일만 갖고 있어서, 그걸 꺼내 매번 다시 디코딩하는 과정을 거쳐야 한다.

경로로 보면 이렇다.

메모리 캐시 히트:  RAM(비트맵) ─────────────▶ 화면            (거의 즉시)
디스크 캐시 히트:  디스크 → 디코딩 → RAM ────▶ 화면            (디코딩 비용 발생)
캐시 미스:        네트워크 → 디스크 → 디코딩 → RAM ─▶ 화면    (다운로드 + 디코딩)


4. 그래서 캐시 타이밍이 이렇게 정해진다

1) "메모리 캐시를 너무 자주 비우면 깜빡인다"의 정체

메모리 캐시를 비워도 디스크에 압축 파일은 남아 있으므로 네트워크 재다운로드는 발생하지 않는다. 하지만 화면에 다시 그리려면 디스크 → 디코딩 → RAM 경로를 다시 밟아야 한다. 이 찰나의 디코딩 비용/지연이 미세한 깜빡임으로 보이는 것이다.

즉 메모리 캐시 정리는 네트워크 재다운로드보다는 싸지만, 디코딩 비용까지 공짜인 건 아니다. 그래서 화면 전환마다 비우지 말고 확실한 분기점(무거운 화면 unmount, 백그라운드 전환)에서만 비운다.


2) 디스크 캐시 정리가 훨씬 비싼 이유

디스크 캐시를 비우면 압축 원본까지 사라지므로, 다음엔 네트워크 다운로드 + 디코딩을 처음부터 다 해야 한다. 되돌릴 수 없는 데다 셀룰러 데이터까지 쓰므로, 사용자가 명시적으로 동의한 시점(설정의 캐시 지우기, 로그아웃)에서만 건드린다.


3) 프리로드가 깜빡임을 없애는 원리

프리로드는 화면 진입 전에 미리 다운로드와 디코딩을 끝내 비트맵을 메모리에 올려두는 것이다. 그래서 실제 화면이 뜨는 순간엔 메모리 캐시 히트가 되어 디코딩 없이 바로 그려진다. 깜빡임의 정체가 "진입 시점의 디코딩 지연"이므로, 그 디코딩을 앞당겨 끝내는 게 프리로드의 본질이다.



5. 실무에서 디코딩 비용을 줄이는 법

  • 원본 그대로 넣지 않는다. 썸네일 자리에 4000×3000 원본을 넣으면, 화면엔 작게 보여도 디코딩 시 48MB짜리 비트맵이 그대로 만들어진다. 서버/CDN에서 표시 크기에 맞춘 리사이즈 이미지를 내려받는 게 가장 효과가 크다.
  • resizeMode만으론 메모리가 줄지 않는다. resizeMode는 이미 디코딩된 비트맵을 어떻게 배치·크롭할지의 문제라, 디코딩되는 픽셀 수 자체(=메모리)는 원본 해상도 기준으로 잡힌다. 메모리를 줄이려면 소스 해상도 자체를 줄여야 한다.
  • 리스트에서 동시 디코딩 수를 통제한다. FlatList/FlashList에서 화면 밖 대량 아이템을 한꺼번에 렌더하면 그만큼 동시 디코딩이 몰린다. windowSize, maxToRenderPerBatch 등으로 조절한다.
  • WebP 등 효율적 포맷을 고려한다. 파일 크기(다운로드·디스크)는 줄지만, 디코딩 후 RAM 점유는 포맷과 무관하게 해상도로 결정된다. 포맷 최적화는 네트워크/디스크에 효과가 있고, 메모리는 결국 해상도가 좌우한다는 점을 구분한다.


6. 한 줄 정리

디코딩은 압축된 이미지 파일 → 화면에 그릴 픽셀 비트맵으로 푸는 CPU 작업이고, 이 과정에서 용량이 수십 배로 불어난다.

  • 메모리 캐시는 디코딩 끝난 비트맵을 들고 있어 즉시 그린다.
  • 디스크 캐시는 압축 원본만 들고 있어 매번 다시 디코딩한다.
  • 프리로드는 디코딩을 미리 끝내 진입 시 깜빡임을 없앤다.

캐시 타이밍의 모든 판단은 결국 "이 디코딩을 언제 치를 것인가"의 문제로 수렴한다.

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

0개의 댓글