이미지 최적화란?
이미지 최적화는 웹사이트의 성능과 속도를 향상시키기 위해 품질을 손상시키지 않으면서 이미지의 파일 크기를 줄이는 프로세스입니다. 이 프로세스에는 크기를 최소화하면서 최상의 형식, 크기, 해상도 및 품질로 이미지를 제공하는 것을 목표로 하는 여러 기술과 도구가 포함됩니다.
즉, 품질을 손상시키지 않으면서 크기를 최소화하여 최적화한다는 것이죠.
이미지 최적화를 해야되는 이유?
1. 로딩 속도 개선
- 최적화된 이미지는 더 빠르게 로드되어 더 원활한 탐색 환경을 제공합니다.
2. SEO 우선순위 향상
- 검색 엔진은 빠르게 로딩되는 웹사이트를 우선시합니다. 최적화된 이미지는 로드 시간을 단축하여 검색 엔진 순위를 향상시킵니다.
3. 향상된 사용자 경험
- 빠른 로딩 시간과 반응형 이미지는 연결 속도가 느린 모바일 장치에서 사용자에게 더 좋은 경험을 제공합니다.
4. 저장 비용 절감
- 파일 크기가 줄어들면 필요한 저장 공간이 줄어들어 웹사이트 호스팅 비용을 절감할 수 있습니다.
Next.js에서 이미지 최적화 방법
대표적인 방법은 이미지 포멧을 변경하여 파일 크기를 최소화할 수 있습니다.
이미지 포맷 형식에는 jpg, png, webp, gif 등이 있습니다.
이미지의 다양항 형식을 이해할 때 중심점이 되는 것은 압축형식입니다.
손실 압축 vs 무손실 압축
- 손실 압축
- 이미지의 품질을 희생하고 더 적은 용량을 선택한 방식
- 고품질 이미지가 필요하지 않은 웹 사용에 종종 허용됩니다.
- 저장을 하면 자동으로 이미지가 손실되며, 저장이 누적될수록 손실도 누적
- 대표적으로 jpg파일이 손실 압축에 해당합니다. - 무손실 압축
- 이미지 품질 저하 없이 파일 크기를 줄입니다.
- 불필요한 메타데이터를 제거하고 효율적인 인코딩을 사용하여 파일 크기를 줄입니다.
- png, webp, gif파일이 무손실 압축에 해당합니다.
서버에서 클라이언트로 이미지를 불러올 때
next/image의 <Image>를 사용하면 Next가 알아서 webp등의 최신 형식의 이미지로 불러옵니다.
이미지 로딩속도가 자동으로 최적화 됩니다.
하지만 서버에 올릴때는 어떻게 해야 될까요?
서버에 이미지를 올릴때에는 'sharp'라는 라이브러리를 사용하면 됩니다.
sharp 라이브러리의 소개를 보면 다양한 차원의 더 작은 JPEG, PNG, WebP, GIF 및 AVIF 이미지로 변환하는 것이라고 소개 되어 있습니다. 그리고 변환해 주는 속도도 매우 빠르다라고 나와있습니다.
sharp 사용법
npm 또는 Yarn을 사용하여 Sharp를 설치합니다.
npm install sharp
yarn add sharp
sharp를 적용하기 전 이미지 업로드 코드
//기존 코드
export async function uploadItem(_: any, formData: FormData) {
const data = {
photo: formData.get("photo"),
title: formData.get("title"),
price: formData.get("price"),
description: formData.get("description"),
};
if (data.photo instanceof File) {
const photoData = await data.photo.arrayBuffer();
const params = {
Bucket: bucketName!, //bucketName이 undefined가 아님을 명시적으로 알림
Key: data.photo.name,
Body: Buffer.from(photoData),
ContentType: data.photo.type,// <= 기존의 파일을 그대로 가져옴
};
try {
const uploadResult = await s3.upload(params).promise();
data.photo = uploadResult.Location;
} catch (error) {
console.error("Failed at this point:", error);
}
}
...
이 코드의 문제는 사용자가 넣은 이미지 파일을 그대로 업로드하기 때문에 이미지 최적화가 안되어 있는 코드입니다.
이 코드를 sharp를 사용하여 개선해 보겠습니다.
sharp를 적용한 이미지 업로드 코드
import sharp from "sharp";
export async function uploadItem(_: any, formData: FormData) {
const data = {
photo: formData.get("photo"),
title: formData.get("title"),
price: formData.get("price"),
description: formData.get("description"),
};
if (data.photo instanceof File) {
const photoData = await data.photo.arrayBuffer();
// Sharp를 사용하여 이미지 최적화
const optimizedPhoto = await sharp(Buffer.from(photoData))
.webp({ quality: 95 }) // WebP 형식으로 변환 및 무손실 압축 품질 설정
.toBuffer();
const imgName = `${Date.now()}-${data.photo.name.split(".")[0]}.webp`;
//Sharp를 사용하여 webp형식으로 바꿨으니 파일명도 webp 형식으로 바꿔줌
const params = {
Bucket: bucketName!, // bucketName이 undefined가 아님을 명시적으로 알림
Key: imgName, // webp 형식으로 바꾼것을 고유키로 들고옴
Body: optimizedPhoto, // sharp 이미지 최적화 파일을 들고옴
ContentType: "image/webp", // 변환시킨 webp 형식으로 타입을 정해줌
};
try {
const uploadResult = await s3.upload(params).promise();
data.photo = uploadResult.Location;
} catch (error) {
console.error("Failed at this point:", error);
}
}
...
결과물 비교
PNG → Webp 변환
원본 파일은 790.0KB
sharp를 이용한 변환 파일은 126.6KB
이미지 크기를 비교했을 때 약 83.9%의 차이가 났습니다.
서버에서 클라이언트로 불러올 때는 next/image의 <Image/>!
클라이언트에서 서버로 업로드할 때는 sharp!
결론
Next.js에서 기본적으로 제공해주는 최적화 도구와 다양한 라이브러리를 함께 적용하면
더 나은 최적화 전략을 적용할 수 있습니다.

sharp 라이브러리 적용 후 vercel 배포 시 런타임 오류 발생
[Next.js] sharp 라이브러리 적용 후 vercel 배포 시 런타임 오류 발생
문제상황https://taehyeon-smilestudy.tistory.com/51 [Next.js] AWS S3 업로드 이미지 최적화를 해보자! (feat. sharp)이미지 최적화란?이미지 최적화는 웹사이트의 성능과 속도를 향상시키기 위해 품질을 손
taehyeon-smilestudy.tistory.com
'코딩이야기 > Next.js 공부' 카테고리의 다른 글
[React] useFormStatus를 사용한 pending 상태 추적 (0) | 2024.09.09 |
---|---|
[Next.js] Prisma 개념 및 사용법 (1) | 2024.06.11 |