갤러리에서 처음 사용자가 이미지를 올릴 때 용량제한을 두지않아 이미지가 용량이 크고 양이 많아질수록 페이지 로드되는 속도가 현저히 낮아지는 현상발생
setImgSrc((prev) => [...prev, e.target!.result as string]);// 이미지 파일받기
const OnChangePhoto = (e: ChangeEvent<HTMLInputElement>) => {
if (onClickUserCheck(e)) return;
const files = e.target.files;
setCurrentRegion(e.target.id.split('-')[1]);
if (!files) return;
Array.from(files).forEach((file) => {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = (e) => {
if (typeof e.target?.result === 'string' && e.target.result) {
if (activeTab === 'allTab') {
setImgSrc((prev) => [...prev, e.target!.result as string]);
// setIsRigionModal(true);
openModal();
} else if (activeTab === 'rigionTab') {
setImgSrc((prev) => [...prev, e.target!.result as string]);
setRegionCate(item);
}
}
};
});
};
// 이미지 파일받기
const OnChangePhoto = async (e: ChangeEvent<HTMLInputElement>) => {
if (onClickUserCheck(e)) return;
const files = e.target.files;
setCurrentRegion(e.target.id.split('-')[1]);
if (!files) return;
const imgSrcArray: string[] = await Promise.all(
Array.from(files).map(async (file) => {
// 파일 압축
const compressedImage = await imageCompression(file, {
maxSizeMB: 1, // 1MB
maxWidthOrHeight: 1024, // 이미지의 최대 가로 또는 세로 길이를 1024로 제한
useWebWorker: true // 압축 작업이 메인 스레드에 영향을 미치지 않도록 설정
});
// 압축파일 AVIF 형식으로 변환
const avifImage = await convertImageToAvif(compressedImage);
// 압축된 파일 읽기
return new Promise<string>((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(avifImage);
reader.onload = () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
}
};
});
})
);
// 상태 업데이트를 한 번에 처리
setImgSrc((prev) => [...prev, ...imgSrcArray]);
if (activeTab === 'allTab') {
openModal();
} else if (activeTab === 'rigionTab') {
setRegionCate(item);
}
};
Promise.all 사용해 파일 압축 & 읽기 -> 병렬로 처리
-> 병렬로 처리하면 하나끝날때까지 안기다리고 여러개를 동시에 처리가 가능해 시간단축이 가능하고, 코드가 좀 더 깔끔해진다.
반복됬던 상태 업데이트를 한 번에 처리하여 불필요한 렌더링을 방지
setImgSrc((prev) => [...prev, ...imgSrcArray]);
전달받은 압축된이미지를 한 번 더 AVIF 형식으로 변환
// AVIF 형식으로 변환하는 함수
export const convertImageToAvif = (file: File): Promise<File> => {
return new Promise((resolve) => {
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx?.drawImage(img, 0, 0);
canvas.toBlob(
(blob) => {
if (blob) {
const webpFile = new File([blob], `${file.name.split('.')[0]}.webp`, { type: 'image/webp' });
resolve(webpFile);
} else {
console.warn('WebP 변환 실패, 원본 파일 사용');
resolve(file);
}
},
'image/webp',
0.8
);
};
img.onerror = () => {
console.warn('이미지 로드 실패, 원본 파일 사용');
resolve(file);
};
});
};
실제로 이미지용량이 줄었다.
성능이 좀 올라갔다.
화면에 앨범제외하고도 pc에서만 나타나는 푸터로 큰레이아웃변경이 원인일 수 있다.
(BF)


(AF)

