만족

cloudflare image + r2 를 이용한 이미지 최적화 서빙 본문

cloudflare image + r2 를 이용한 이미지 최적화 서빙

Backend/기타 Satisfaction 2026. 8. 25. 22:08

 

openapi 를 통해 이미지를 서빙해야 할 때, 서비스 점검 또는 서버 다운 때에도 정상적으로 이미지를 표시하기 위해 내 서버에 이미지를 캐시하여 서빙하고 있다.

 

"이미지 캐시 체크 -> 있으면 반환 후 종료, 없으면 다운로드 -> quality: 80 으로 용량 압축 -> 저장 및 반환 후 종료" 과정으로 제공하고 있는데, 이미지의 갯수가 생각보다 많다 보니 빈번한 용량 압축이 발생해 간간히 cpu spike가 발생한다.

 

cloudflare worker 전환을 진행하면서 cloudflare image + r2 를 이용해 이미지 압축/캐싱 전략을 수정해보았다.

 

Cloudflare image

cloudflare image 는 이미지 변환을 제공하는 플랫폼이다.

 

월 5천 건까지 무료 변환을 지원한다.

 

속도는 빠르지 않지만, worker 환경에서 이미지 변환을 수행하면 cpu time 을 꽤 잡아먹기 때문에 변환 작업은 cloudflare image를 사용하였다.

 

원본 이미지는 png인데, 아시다시피 png 는 무손실 압축 방식을 사용하기 때문에 사이즈가 꽤 크다.

 

 

그런데 표시되는 이미지는 64px*64px 밖에 안 되는 작은 사이즈이기 때문에 그렇게 고화질/무손실을 고집할 필요가 없다.

 

따라서 png -> webp(quality: 80) 으로 변환하도록 설정했다.

 

webp는 png와 달리 손실 압축 방식을 지원하고(무손실도 가능), 사람의 눈으로는 구별이 어려운 정보들까지 버리기 때문에 손실압축 webp는 png보다 압도적으로 작은 크기를 갖는다.

 

이전에는 png를 유지하면서 quality만 80으로 낮췄지만, webp로 변환하면서 quality를 80으로 낮추니 최종 크기는 거의 10% 수준으로 줄어들었다.

 

Cloudflare r2

매 요청마다 이미지 변환이 발생한다면 난 거지가 될 것이다...

 

변환된 이미지는 cloudflare r2 에 저장하고, 이후에는 r2 에 저장된 이미지를 그대로 반환한다.

 

cloudflare r2는 aws s3와 비슷한 서비스라고 보면 된다.

 

한 가지 특이한 점은 cloudflare r2는 트래픽 기반의 요금이 없고, 저장 용량과 class A(리스팅, 수정, 삭제, 추가 등)/B(조회 등) 작업에 대해서만 과금한다.

 

게다가 10GB 용량, class A는 월 백만 건, class B는 월 천만 건의 무료 사용량을 제공한다.

 

 

초과 시에도 나쁘지 않은 가격이라 s3 대신 r2를 선택했다. 

 

물론 무료 사용량의 절반도 사용하지 않고 있다.

 

최종 로직

 

개선 전: "이미지 캐시 체크 -> 있으면 반환 후 종료, 없으면 다운로드 -> quality: 80 으로 용량 압축 -> 저장 및 반환 후 종료"

개선 후: "이미지 캐시 체크 -> 있으면 반환 후 종료, 없으면 다운로드 -> (cf image) webp + quality: 80 으로 변환 -> (cf r2) 저장 및 반환 후 종료"

 

 

개선 전,후 비교

 

비교 대상 페이지에서 개선 전에는 이미지 다운로드 용량 8.6MB, finish 1.2s, DOMContentLoaded 208ms, load 447ms 로 측정되었다.

 

 

개선 후에는 이미지 다운로드 용량 0.9MB, finish 0.97s, DomcontentLoaded: 227ms, load 382ms 로 측정되었다.

 

이미지 용량은 극적으로 줄어들었지만, cloudflare 를 사용하면 TTFB가 늘어지면서 전체 로딩 시간은 큰 차이를 보이지 않고, 오히려 단건 이미지 로딩을 보면 로딩 시간이 더 증가한다.

(참고: https://satisfactoryplace.tistory.com/284)

 

하지만 네트워크 속도를 fast 4g로 쓰로틀하면 

 

개선 전
개선 후

 

용량이 크게 준 덕분에 finish 시간에 큰 차이를 보인다.

 

slow 4g, 3g로 내려갈수록 더욱 개선 효과가 크게 나타난다.

 

또한 nodejs + expressjs 에서 직접 이미지 변환/저장/반환을 하다가 worker + r2 + image 를 사용한 덕에 이미지 변환 요청이 몰려도 애플리케이션의 속도와 안정성에는 전혀 영향을 미치지 않게 되었다.



Comments