본문 바로가기

🌼 TIL

Next.js 이미지 최적화 작업 -Image 태그

프로젝트 초기 유저 50명에게 피드백을 받았다
여기서 약 33%의 인원이 이미지 다운로드 속도에 불편함을 느끼고 있었다.

 

https://docs.google.com/spreadsheets/d/1IalNNg2JjwTLLLNEvK1Z4rQ6riLbRE69wWgkOHuP6Dc/edit?resourcekey#gid=167254231

 

Picspot 사용자 피드백 설문 (응답)

설문지 응답 시트1 타임스탬프,동의하지 않으시면 설문 참여가 불가합니다. ,성함을 기재해주세요.,추첨을 통해 상품을 받으실 전화번호를 기재해주세요. 예) 010-1234-5678 ,사용환경과 운영 체제

docs.google.com

 

 

많은 사람들이 이렇게 느끼는 원인

너무 많은 양의 이미지를 받아오는 과정에서 발생하는 문제였다. 이미지 최적화가 필요했다.

 

해결 방법

많은 양의 이미지 데이터를 가져오기에 이미지 최적화가 필요하다 

- Next.js에서 제공하는 <Image>컴포넌트를 사용

- browser-image-compression 라이브러리 사용하여 이미지 파일 압축

 


Next.js의  <Image>컴포넌트

이미지를 최적화하는 여러 방법 중에서 Next.js에서 제공하느 Image컴포넌트를 발견하게 되었다.

Image컴포넌트는 자동으로 이미지를 최적화해주는 등 성능향상을 해주는 기능이다.

 

장점

- Imporved Performance : 각 디바이스의 사이즈에 맞게 최적화된 이미지를 제공

- Lazy loading 자동 제공 : 불필요한 데이터를 제외, 필요한 데이터만 먼저 불러와 이미지가 뷰포트에 있어 필요할 때만 이미지를 불러옴

- Visual Stability : 이미지 너비, 높이를 명시하여 이미지 공간을 확보할 시 CLS(사이트 레이아웃 안정성)를 안정화함

  - 로컬 이미지 : 너비,높이 자동 파악

  - 원격 이미지 : 너비,높이 지정 필요 (지정하지 않을시 에러 발생) 

- 접근성 개선 : alt텍스트를 포함하여 웹 접근성을 향상

 

Next.js에서 자동제공해주기에 사용법은 간단하다

 import Image from 'next/image';
 
 
  <Image
           src={item?.imgUrl}
           alt="postImg"
           width={150}
           height={200}
           priority={true}
           onClick={saveScroll}
           className="image-box"
           quality={75}
         />

이렇게 Image컴포넌트를 사용하여 이미지 최적화를 진행하였다. 

하지만 클라이언트측에서 이미지 데이터 크기를 압축하기 위해 또 다른 방법을 함께 사용하기로 했다.

 


browser-image-compression

이미지를 압축하고 최적화하는데 사용되는 Javascript 라이브러리이다.

클라이언트측에서 압축하고 따라서 웹브라우저에서 압축이 이루어지며, 이미지 최적화 및 웹페이지 성능을 향상시킨다.

 

이미지를 클라이언트 측에서 압축할 시 

- 브라우저에서 이미지를 처리하므로 서버 리소스가 필요하지 않아 리소스를 절약

- 사용자 경험을 향상

합니다.

const handleImageChange = async (e: any) => {
    let file = e.target.files;
    if (file.length === 0) {
      return;
    } else {
      const {
        currentTarget: { files },
      } = e;

      const options = {
        maxSizeMB: 1, //* 허용하는 최대 사이즈 지정
        maxWidthOrHeight: 500, //* 허용하는 최대 width, height 값 지정
        useWebWorker: true, //* webworker 사용 여부
      };

      let theFile = files[0];

      try {
        const compressedFile = await imageCompression(theFile, options); 
        // 압축된 이미지를 리턴받는다.(imageCompression)

        const reader = new FileReader();
        reader?.readAsDataURL(compressedFile); // 여기에 compressedFile 변수를 넣어주면 끝
        reader.onloadend = (finishedEvent) => {
          const {
            currentTarget: { result },
          }: any = finishedEvent;
          setImageUpload(result);
        };
      } catch (error) {
        console.log(error);
      }
    }
  };

사용법은 간단하며 이미지를 압축하고, 로컬 이미지 확장자를 webp로 바꾸어 이미지 용량을 줄였다.

 

결과

 

이미지 최적화 전

이미지 최적화 후

이미지가 단절적으로 다운되는 현상이 사라졌고, 

Lighthouse의 Performance점수가 66점 -> 74점으로 향상되었고,

DIAGNOSTIC의 막대한 네트워크 payload 경고가 사라지며 사용자 경험이 향상되었다.