티스토리 뷰
🚀 개요
사진 압축 JS 라이브러리 Broswer-Image-Compression 을 사용해 보니 다음과 같은 장점을 느꼈습니다. 손쉬운 사용, 직관적이고 강력한 옵션, 용량 자체가 다른 라이브러리에 비해 가벼웠습니다.
반면에 사진의 압축 시 원본의 변형이 생각보다 더 많이 일어났습니다
😵 사진 용량에 낭비가 심하다
기존에 작업한 프로젝트에서 유저 이미지 파일을 받는 부분이 있는데, 화면에서 100px X 100px 정도의 작은 사이즈임에도 큰 리소스를 잡아 먹는 것을 보고 사진을 압축하기로 결정했습니다
화면에 정말 작은 사이즈가 나타남에도 큰 용량과 큰 사이즈의 사진을 받기도 합니다. 위 사진은 사진의 원래 크기 564*352 px 이지만 실제 화면에 보이는 크기가 가로 세로 100px 이므로 쓸데 없는 용량을 낭비한 것으로 확인할 수 있습니다.
또한 고화질이 필요하지 않는 부분에서는 42.4kB까지의 용량이 너무 과하다고 생각됩니다. 그래서 압축하는데 라이브러리를 사용하기로 했습니다.
🧐 Broswer-Image-Compression 선택
우선 통상적으로 이미지 압축에 두가지 라이브러리를 사용한다는 것을 알았습니다.
1. react-image-file-resizer
2. broswer-image-compression
결과적으로 broswer-image-compression을 선택했는데, 이 라이브러리가 다른 라이브러리에 비해 용량(863kB)이 두배 가량 작아 현재 번들 사이즈 최적화를 진행중인 프로젝트에 더 적합했습니다,
또한 현재 프로젝트에서 차세대 파일 확장자로 변경하던 터라, 이미지 확장자 지정할 수 있는 것에서 더 적합했습니다. 또한 최대 너비/높이를 지정이 가능했으며, 또한 최대 용량을 지정할 수 있었습니다.
https://www.npmjs.com/package/browser-image-compression
😛 해결 방법
1. 간단하게 라이브러리를 다운받고 (npm i broswer-image-compression)
2. 사용하고 싶은 곳에서 import 해온 뒤
3. 비동기 처리로 option들을 지정했습니다.
옵션들에는 다음과 같이 존재하므로 사용하고 싶으신 옵션들을 확인하셔서 사용하시면 되겠습니다.
// you should provide one of maxSizeMB, maxWidthOrHeight in the options
const options: Options = {
maxSizeMB: number, // (default: Number.POSITIVE_INFINITY)
maxWidthOrHeight: number, // compressedFile will scale down by ratio to a point that width or height is smaller than maxWidthOrHeight (default: undefined)
// but, automatically reduce the size to smaller than the maximum Canvas size supported by each browser.
// Please check the Caveat part for details.
onProgress: Function, // optional, a function takes one progress argument (percentage from 0 to 100)
useWebWorker: boolean, // optional, use multi-thread web worker, fallback to run in main-thread (default: true)
libURL: string, // optional, the libURL of this library for importing script in Web Worker (default: https://cdn.jsdelivr.net/npm/browser-image-compression/dist/browser-image-compression.js)
preserveExif: boolean, // optional, use preserve Exif metadata for JPEG image e.g., Camera model, Focal length, etc (default: false)
signal: AbortSignal, // optional, to abort / cancel the compression
// following options are for advanced users
maxIteration: number, // optional, max number of iteration to compress the image (default: 10)
exifOrientation: number, // optional, see https://stackoverflow.com/a/32490603/10395024
fileType: string, // optional, fileType override e.g., 'image/jpeg', 'image/png' (default: file.type)
initialQuality: number, // optional, initial quality value between 0 and 1 (default: 1)
alwaysKeepResolution: boolean // optional, only reduce quality, always keep width and height (default: false)
}
imageCompression(file: File, options: Options): Promise<File>
💡결과
결과적으로 다음과 같이 절반가량 용량을 줄일 수 있었습니다. 손쉬운 사용과 직관적인 옵션들로 사용하기는 쉬웠고, 라이브러리의 용량 자체가 다른 라이브러리에 비해 가벼웠습니다.
하지만 사진들의 압축이 일어나면 생각보다 원본의 변형이 더 일어나는 것 같습니다. 위 같은 경우 100px의 사진을 렌더링 하기에 최대 너비/높이를 100px로 두니 원본에 비해 많이 흐릿함을 느꼈습니다. 그래서 최대 높이/너비 설정을 여유롭게 150px로 잡아서 용량 최적화와 원본 훼손을 최소화 하는 트레이드 오프를 잡을 수 있었습니다.
참조
https://www.npmjs.com/package/browser-image-compression
browser-image-compression
Compress images in the browser. Latest version: 2.0.2, last published: 7 months ago. Start using browser-image-compression in your project by running `npm i browser-image-compression`. There are 122 other projects in the npm registry using browser-image-co
www.npmjs.com
'웹 개발' 카테고리의 다른 글
[프론트엔드 CI/CD 적용] React 프로젝트, Github Actions, Netlify 이용한 CI/CD 자동화 적용기 (2) | 2023.10.05 |
---|---|
[리팩토링/성능개선] 스켈레톤 UI 적용하기 JS과제 리팩토링 (0) | 2023.08.28 |
[리팩토링 / 성능개선] Opacity변경에서의 Reflow의 발생 (2) | 2023.08.07 |
[리팩토링 / 성능개선] 리팩토링(Intersection Observer) (2) | 2023.08.07 |
[HTML/CSS/Vanilla JS] 스크롤 애니메이션 (2) | 2023.07.27 |
- Total
- Today
- Yesterday
- ci/cd
- 프론트엔드 성능
- Github Actions
- 프론트엔드개발자
- Vercel
- 이미지최적화
- 국비지원취업
- 부트캠프
- 사이드프로젝트
- netlify
- 패스트캠퍼스
- FE 주니어
- 리뷰
- 깃허브 사용법
- next 14
- RARS
- 로딩성능
- 인프콘 2023
- Not Working
- no found
- JavaScript
- 모노레포
- 개발자 회고
- 깃허브
- 성능 개선
- 성능 측정
- kpt
- FE
- 국비지원
- Tailwind CSS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |