이미지 캐싱 처리 개선

Jisu·2023년 9월 5일
0

iOS

목록 보기
2/9

문제점

DB로 부터 음식점 URL을 가져오고, 그 URL을 이용해서 이미지를 띄우는 방식이다. 문제는 이미 fetch 되었던 이미지 데이터라도 클릭할 때 다시 데이터를 받아오는 것이다. 데이터를 다시 받아오면 캐싱처리도 초기화된다는 문제가 있었다.

이는 통신할 때마다 캐싱키가 바뀐다는 것으로 추정했다.
KingFisher는 기본적으로 URL을 캐싱키로 저장하므로 통신해서 받아오는 URL이 계속 달라진다는 것이다. 과연 그럴까?

요청할 때 마다 다르게 오는 이미지 URL

Notion DB에서 이미지 URL을 가져올 때마다 그 URL을 프린트해보았다. 놀랍게도 정말 URL이 달랐던 것이다. 그래서 매번 다른 key로 캐싱키가 설정되니, 요청할 때마다 데이터 로딩이 발생하는 것이다.

AWS에 저장된 URL은 다음과 같은 형태로 돌아온다

여기서 5번 부분인 Signature가 매번 달라지는 것이다.
왜 요청 때 마다 다른 Signature를 주는 것일까?

AWS의 URL 서명 정책

서명(Signature)은 자원에 대한 접근을 제어하는 방식이고 내부에는 URL의 유효기간이 명시되어있다. 왜 유효기간을 둘까? 이유는 돈 때문이다.

AWS는 자체 서버에 이미지를 대신 저장해주고 사용자로 부터 돈을 받는다. 여기서 고객은 Notion인 것이고 Notion은 API를 통해서 이 이미지가 어디에 있는지 Notion API 사용자에게 URL을 준다.

만약 이 URL에 유효기간이 없다면 Notion을 거치지 않아도 누구나 자원에 접근이 가능하므로 Notion은 비용 폭탄을 맞게 된다...

따라서 Notion이 AWS에 요청해서 그 때 그 때 서명이 담긴 URL을 받아오므로 Notion API 요청에 비례하는 요금만 내면 되는 것이다.

자세한 내용은 AWS 공식 홈페이지를 살펴보자

AWS 서명된 URL 정책

따라서 캐싱키를 자체적으로 지정해줘야한다.

이전에 KingFisher를 분석해보면서 Source, Resource를 사용하는 것을 알았다

따라서 KFImage를 URL로 만들어주는 것이 아니라, 직접 Source를 만들어서 주입해준다.

이미지를 만들기 위해서 Source가 필요하다.
Source는 로컬과 네트워크로 나뉜다. 나는 URL을 HTTP통신해서 이미지 데이터를 가져와야하므로 network 케이스로 만들어준다.

네트워크 통신 Source를 만들기 위해서 Resource가 필요하고 ImageResource를 만들기 위해서 두 가지 파라미터가 필요하다.

  1. downloadURL - 자원이 있는 곳의 URL
  2. cacheKey - 옵셔널 값으로 어떤 값으로 캐싱키를 지정할 것인가이다.

여기서는 Notion이 Signature를 바꿔서 URL을 주기 때문에 음식점의 이름을 사용해서 캐싱한다.

결과

이전에 다운로드해왔던 사진이라면 로딩없이 바로 띄우는 것을 확인할 수 있다.
다만 맨 처음 캐싱된 값을 불러오는 동안의 로딩은 발생하고 있다.

의의

3rd Party라고 해서 그냥 가져다쓰는게 아니라
내부 구조를 이해하고 필요에 맞게 또 변형해서 쓸 수 있었던 뜻 깊은 경험이었다.

profile
비즈니스에 관심많은 DevOps Engineer 장지수입니다.

0개의 댓글