프로젝트에서 크게 사용한 부분은 메인페이지에 이미지들이 많이 사용되었는데, Image 컴포넌트의 디자인 에러나 반응형 크기 조절이 잘 안됐기 때문에 처음 목업 작업시에는 img 태그를 사용해서 적용시켰지만, next.js의 프레임워크를 사용하면서 장점중 하나인 Image 컴포넌트를 사용하지 않는 점은 아쉽다고 생각하여 기존 img 태그를 제거하고 Image 컴포넌트로 적용하게 되었다.
간단하게 Image 컴포넌트의 장점을 적자면,
Image 컴포넌트는 이미지 최적화를 자동으로 처리한다. 이미지 최적화는 이미지 크기를 줄이고 품질을 유지
하는 방법으로 페이지 로딩 속도를 향상시키고 사용자 경험을 향상시킬 수 있다. Image 컴포넌트를 사용하고 나서 페이지 렌더링 처리 속도도 매우 빨라져 img 태그보다 이미지가 빨리 나타났고, 실제 서버에 배포했을 때도 기존 img 태그로 인한 도커 서버가 터져서 올리고 사이트에 접속하면 cpu 사용량이 오버되어 터지는 문제가 있었는데 해결된 부분도 있었다.(물론 이미지 확장자나 용량의 문제도 있었지만 Image 컴포넌트의 최적화도 한 몫 했다고 생각한다 이 부분은 배포과정에서 자세히 다룰 예정이다.)
Image 컴포넌트를 사용하면 이미지의 다양한 크기와 해상도에 대한 자동 반응형 처리를 제공할 수 있다. 이는 사용자의 viewport에 따라 최적화된 이미지를 제공하여 모바일 기기에서도 최적의 이미지를 로드할 수 있도록 도와준다. 이 부분에 있어 프로젝트에서 mobile 환경의 반응형 디자인도 적용하였기 때문에 큰 이점으로 다가왔다.
Image 컴포넌트는 이미지를 필요로하는 페이지에 대한 prefetching을 자동으로 처리한다. 이를 통해 이미지가 사용자가 페이지에 도달하기 전에 미리 로드되어 페이지 로딩 시간을 줄이고 사용자 경험을 향상시킬 수 있다.
Image 컴포넌트는 최신 웹 표준인 HTML의 <picture>
요소를 사용하여 이미지를 렌더링한다. 이는 웹 접근성과 검색 엔진 최적화에 도움을 줄 수 있다.
Image 컴포넌트는 이미지 로딩을 지연시키고 스크롤 이벤트와 같은 상호 작용을 처리하여 페이지의 성능을 향상시킨다. 또한, 이미지 렌더링을 서버 사이드 렌더링, Static Generation과 함께 사용할 수 있어 next.js 의 서버 사이드 렌더링의 장점을 이용할 수 있다.
Image 컴포넌트 안에서는 필수적으로 src, width, height의 값을 입력해야 한다 기준은 px이다. width, height을 입력하고 싶지 않다면 layout="fill" 속성을 넣어주어야 한다.
<S.BodyImgBox>
<div>
<Image
src="/img/main/section3_img1.webp"
alt="img"
layout="fill"
objectFit="contain"
loading="lazy"
/>
</div>
<div>
<Image
src="/img/main/section3_img2.webp"
alt="img"
layout="fill"
objectFit="contain"
loading="lazy"
/>
</div>
</S.BodyImgBox>
실제 프로젝트에 Image 컴포넌트를 활용하여 적용한 부분이다. 여기서 Image 컴포넌트로 전달해준 prop 들의 속성들이 무슨 역할인지 알아보자.
이미지 파일의 주소를 적어주면 된다. 만약 로컬 이미지가 아닌 외부 이미지 주소를 적용시킬 경우 next.js 서버측에서 주소에 직접 요청을 하기 때문에 모든 url에 대한 접근을 막기 위해 next.js에게 안전한 서버임을 알려주어야 한다. 아래 코드와 같이 next.config.js 에서 CDN의 도메인에 대한 접근을 허가해야한다.
const nextConfig = {
images: {
domains: ["kr-a.kakaopagecdn.com", "image-comic.pstatic.net"],
},
};
fill: relative 포지션을 가진 부모 요소의 크기에 맞게 채우는 속성이다. 주로 objectFit 속성과 함께 사용된다.
responsive: 작은 컨테이너에서는 크기가 줄어들고, 큰 컨테이너에서는 크기가 늘어난다.(이미지 비율 유지)
fixed: 이미지 사이즈를 width, height 속성 값으로 고정한다.
css의 object-fit 속성과 동일한 효과가 있다.
contain: 이미지의 가로 및 세로 비율을 유지하면서 이미지를 부모 요소에 맞추는 방법을 결정한다. 즉, 이미지가 부모 요소 내에 가능한한 많은 공간을 차지하도록 확대 또는 축소된다.
lazy: 브라우저 창에 보이지 않는 이미지가 있는 경우 로딩을 지연시키고 보이는 이미지만을 로드해서, 불필요한 대역폭 사용을 줄이고 필요한 이미지만 빠르게 로드할 수 있도록 한다.
만약 이러한 기능을 사용하고 싶지 않다면 prioirty="true" 를 사용하여 끌 수 있다.
layout="fill" 을 적용하여 부모 속성의(relative를 가진) 태그를 이용하여 구현할 수 있다. 기본 width, height는 px기준으로 숫자만 입력 가능하기 때문이다.
export const BodyImgBox = styled.div`
height: 600px;
position: relative;
> div:nth-of-type(1) {
position: absolute;
width: 50%;
height: 70%;
left: 0;
}
> div:nth-of-type(2) {
position: absolute;
width: 50%;
height: 70%;
right: 0;
}
`;
이런 방식으로 Image 컴포넌트 부모요소에 div 태그로 감싸 표현하였다.
참고
https://stackoverflow.com/questions/65169431/how-to-set-the-next-image-component-to-100-height
https://fe-developers.kakaoent.com/2022/220714-next-image/