현재 진행 중인 프로젝트에서 안드로이드 기기의 사진을 대량으로 서버로 전송해야 한다.
일단 이미지 50개 정도로 테스트를 해봤는데, 로딩이 생각보다 너무 느렸다.
실제 사용자는 최소 1000장 이상의 사진을 가지고 있을텐데, 최적화가 시급해보인다.
일단 현재 상태를 console.time()을 이용해서 측정해 보았다.
아래는 이미지들을 보내고, 서버로부터 success를 응답 받는데 걸린 시간이다. 두번 측정해 봤는데 대략 10~11초 정도 걸리는 것 같다. (실제로 측정해보니 너무 오래 걸린다..ㅜㅜ)
최적화 시작!
일단 이미지 용량을 줄이는 방법을 가장 먼저 적용해보기로 했다.
react-native-image-resizer를 사용해보자
bamlab/react-native-image-resizer: 🗻 Resize local images with React Native (github.com)
먼저 아래의 코드로 세팅한다.
yarn add @bam.tech/react-native-image-resizer
그리고 공식문서에 나와있는 아래의 코드로 간단하게 이미지 용량을 줄일 수 있다.
import ImageResizer from '@bam.tech/react-native-image-resizer';
ImageResizer.createResizedImage(
path,
maxWidth,
maxHeight,
compressFormat,
quality,
rotation,
outputPath
)
내가 적용한 코드는 아래와 같다.
images?.map(image => {
ImageResizer.createResizedImage(
image.path, // path
windowWidth, // width
windowHeight, // height
'WEBP', // CompressFormat
100, // quality(for JPEG)
0, // rotation
null, // outputPath (null일 경우 cache에 저장)
)
일단 path를 넣어주고, width와 height는 미리 적용한 화면 크기로 넣었다.
(해당 프로젝트에서 사용되는 이미지들은 모두 캡쳐사진이기 때문에 사진 크기가 기기 화면의 크기와 같아야 한다.)
그리고 format type은 WEBP로 설정했다.
보통 JPEG가 많이 사용되지만 WEBP로 사용하면 사진 압축률을 훨씬 올릴 수 있어서 용량을 크게 줄일 수 있다.
WebP란?
구글에서 개발한 파일 포멧으로 인터넷에서 이미지를 로딩하는 시간을 단축하기 위해 만들어졌다.
WebP는 손실압축과 비손실압축을 선택할 수 있는데, 손실 압축의 WebP 이미지는 같은 손실 압축 방식을 사용하는 JPEG 파일보다 25%~34%의 용량을 줄일 수 있다고 한다.
더 자세한 내용은 아래의 링크를 참고하자.
웹용 이미지 형식 | WebP | Google for Developers
아! 그리고 WebP는 ios에서는 아직 호환성 문제때문에 사용하기 힘든 것 같다.
이렇게 이미지 resize를 진행 한 후 다시 한번 똑같이 측정해본 결과 아래와 같이 전송시간이 반절로 줄었다!
한개의 이미지를 정해 사이즈 변화도 측정해 봤다. 왼쪽이 압축 전, 오른쪽이 압축 후의 사이즈이다.
오! 첫번째 사진의 경우에는 압축후에 사이즈가 무려 17% 정도 줄었다.
근데 문제가 생겼다!
분명 내가 자료를 찾아볼 때는 WebP로 압축 했을 때, 사진 화질 저하가 되기는 하지만 육안으로 많이 차이 나지는 않는다고 했다.
그런데 서버로부터 저장된 사진을 다시 확인해본 결과 생각보다 화질저하가 많이 느껴진다.
사진이 전체적으로 흐릿한 느낌이다.
내 생각에는 아무래도 애초에 사진이 다운로드된 사진이 아니라 화면을 캡쳐한 사진이다 보니 고화질이 아니어서 압축했을 때 더 저화질로 느껴질 수도 있을 것 같다.
아무튼! 아무리 로딩 시간이 줄었어도 화질이 이렇게까지 저하되는건 안된다.
혹시 JPEG로 압축하면 좀 나을까?
JPEG로 위의 테스트를 똑같이 해 보았다.
왼쪽부터 차례대로 압축전, WebP 압축, JPEG 압축 했을 경우 이미지 사이즈이다.
JPEG의 압축률은 8%로, WebP에 비해 2배 떨어진 압축률이다.
또한 전송시간은 아래와 같다.
마찬가지로 왼쪽 부터 압축전, WebP 압축, JPEG 압축 순이다.
사이즈가 더 커졌으므로 당연하겠지만 WebP보다는 전송시간이 조금 더 걸린다.
근데 이미지 사이즈가 커졌다고 화질이 좋아지는건 아닌가보다.
WebP와 비교했을 때 전혀 더 나아진 느낌 없이 똑같이 흐릿했다..
아래는 왼쪽부터 압축전, WebP 압축, JPEG 압축 순 사진이다. 육안으로 봐도 글씨가 확 흐릿한 느낌이 든다.
그렇게 이미지 압축을 실제로 해본 결과 생각보다 낮은 화질때문에 실제로 적용은 못할 것 같다.
화질이 높거나, 이미지 크기가 크다면 해당 방식으로 용량을 줄이는게 적합할 수 있겠지만, 캡쳐사진에 적용하기에는 어려울 듯 하다.
계속해서 다른 방법으로 로딩시간을 줄여야 겠다!
'react-native' 카테고리의 다른 글
[react-native] 입력 창 연속해서 이동하며 focus 하기(2) - useRef 여러개를 배열로 관리하기 (0) | 2023.04.05 |
---|---|
[react-native] 입력 창 연속해서 이동하며 focus 하기(1), 컴포넌트로 ref 넘기기, forwardRef (0) | 2023.04.02 |
[react-native] 라이브러리 없이 캘린더 직접 구현하기 (0) | 2023.03.31 |
[react-native/recoil] recoil selector 사용하기 (0) | 2023.03.12 |
[react-native/recoil] atom을 서버와 연동하기 (0) | 2023.01.06 |