카테고리 없음
[트러블 슈팅&최적화] 프로필 이미지 업로드 문제
올바른생활부터
2024. 7. 26. 14:48
728x90
반응형
SMALL
목차
1. 문제 발생
2. 문제에 대한 정보 수집&원인 추론
3. 문제 해결
1. 문제 발생
- 프로필 이미지 업로드 시 크기가 큰 이미지를 업로드할 경우 API 요청 실패 및 인증 토큰 만료 문제가 발생하여 로그인된 유저가 로그아웃되는 현상이 발생하였다.
// apiConfig.tsx
/**
* 응답 인터셉터 설정
* 로그인 토큰이 만료되었을 때, 로그인 페이지로 이동
*/
client.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (error.response && error.response.status === 401) {
// 토큰 만료 시 로그인 페이지로 이동
window.location.href = '/signin';
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
}
return Promise.reject(error);
},
);
// Mypage.tsx
/**
* 이미지 파일 변경 시 호출되는 함수
* @param event
*/
const handleImgChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
setSelectedFile(file);
setImgUrl(URL.createObjectURL(file));
}
};
/**
* 이미지 업로드 함수
*/
const handleImgUpload = async () => {
if (selectedFile) {
const formData = new FormData();
formData.append('imageFile', selectedFile);
let response;
if (oldImageUrl && oldImageUrl !== 'undefined') {
response = await fetchUserImgPut(formData, oldImageUrl);
} else {
response = await fetchUserImgPost(formData);
}
if (response?.data.result_code === '200') {
alert('프로필 사진이 등록되었습니다.');
const newImgUrl = response.data.data;
setImgUrl(newImgUrl);
login({ ...user, img_url: newImgUrl } as User);
} else {
alert('프로필 사진이 등록되지 않았습니다.');
console.error(response?.data.error.error_message);
}
}
};
return (
<Button
onClick={handleImgUpload}
border="1px solid"
borderRadius=".5rem"
background="main"
textColor="white"
padding="1.5rem">
<Text fontSize="1.5rem">등록</Text>
</Button>
...
)
2. 문제에 대한 정보 수집&원인 추론
- 초기 추정: 문제의 원인이 AWS S3 버킷 설정에서 최대 파일 크기 제한에 있다고 생각했다. 하지만 AWS S3는 큰 파일도 저장할 수 있기 때문에, 이 부분은 문제의 원인으로 판단되지 않았다.
- 백엔드 개발자와의 논의: 이슈를 백엔드 개발자에게 문의한 결과, "이전에도 이미지 크기 제한과 관련된 유사한 상황이 발생한 적이 있다"라고 전달 받았고, API 서버에서 클라이언트가 업로드할 수 있는 파일 크기를 제한하고 있을 가능성이 있다 판단했다.
3. 문제 해결
- 문제를 해결하기 위해 react-image-file-resizer 라이브러리를 사용하여 클라이언트 측에서 이미지 파일을 자동으로 리사이징했다. 이 라이브러리는 업로드 전에 이미지 파일을 더 작은 크기로 줄이며, 리사이징 후 이미지 파일을 Blob 형식으로 변환하여 클라이언트 측에서 처리 및 저장하도록 했다.
- 이렇게 함으로써, 큰 용량의 이미지를 최적화하여 업로드할 수 있게 되었고, 원래 220KB였던 이미지를 70KB로 최적화 하였다. 이는 68%의 크기 감소를 하였으며, 서버 사용을 최적화하고 전송 속도를 향상시켰다. 결과적으로, 네트워크 사용량 감소와 빠른 로딩 시간은 사용자 경험을 크게 향상시켰다.
react-image-file-resizer 라이브러리를 사용한 이유는, 이미지를 업로드한 그대로 사용하지 않고, 클라이언트 측에서 미리 리사이징하여 이미지의 크기를 줄임으로써 서버와 데이터베이스의 부담을 줄이기 위해서입니다. 이를 통해 서버의 저장 공간 사용을 최적화하고, 대량의 이미지 파일 처리 시 발생할 수 있는 성능 저하를 방지하며, 전송 속도를 개선해 전체적인 사용자 경험을 향상시킬 수 있습니다.
import FileResizer from 'react-image-file-resizer';
...
/**
* 이미지 파일 변경 시 호출되는 함수
* @param event
*/
const handleImgChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
FileResizer.imageFileResizer(
file,
300,
300,
'WEBP',
100,
0,
(uri) => {
setSelectedFile(uri as File);
setImgUrl(URL.createObjectURL(uri as Blob));
},
'blob',
);
}
};
react-image-file-resizer 적용 전
[크기가 큰 이미지1]
[크기가 작은 이미지2]
react-image-file-resizer 적용 후
[크기가 큰 이미지1]
[크기가 작은 이미지2]
728x90
반응형
LIST