search : URL에서 쿼리 문자열을 필터링할 수 있는 옵션. 기본적으로 빈 문자열(' ')로 설정하면 모든 쿼리를 허용
#2. Remote Images
Remote Images를 사용하기 위해서는 src 속성에 URL 주소를 넣어주면 된다.
Next.js는 빌드 과정동안 remote files에 접근할 수 없기 때문에, width와 height가 반드시 필요하며 선택적으로는 blurDataURL을 제공해야 한다. 반면, Local Images를 사용할 때는 이미지가 로컬에 존재하기 때문에 width, height를 입력하지 않아도 Next.js는 해당 이미지에 대한 정보를 알 수 있다.
import Image from 'next/image'
export default function Page() {
return (
<Image
src="https://s3.amazonaws.com/my-bucket/profile.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
💡 remotePatterns
외부에서 임의의 이미지를 가져와 최적화할 경우, 악의적인 URL로 인해 보안 문제가 발생할 수 있다.
remotePatterns는 허용된 URL 패턴만 이미지 최적화에 사용할 수 있도록 제한한다.
특정 프로토콜, 호스트명, 경로 패턴 등을 지정하여 Next.js가 어떤 외부 이미지를 최적화할 지를 결정할 수 있다.
layout 속성은 image 요소를 사용했을 때 이미지가 어떤 형태로 보여주어야 하는지 정의하는 기능을 제공한다.
Next.js 13 버전 이후로는 layout="intrinsic" 값이 default로 사용된다.
하지만 intrinsic 값 외에도 상황에 맞게 아래와 같은 layout 속성을 이용할 수 있다.
intrinsic (default) : 원본 이미지 크기로 렌더링하고 화면의 크기에 맞춰 자동으로 resizing
fixed : 컨테이너 크기에 상관없이 이미지 크기가 고정
responsive : 작은 컨테이너에는 크기가 줄어들고, 큰 컨테이너에서는 크기에 맞춰 width 값이 계속 증가
fill : 원본 이미지의 사이즈를 모를 때 사용. 부모 요소에 position: relative를 꼭 넣어주어 부모 요소의 크기 설정을 해줘야 함
💡 Next.js 13이상 버전에서 layout 속성 사용 방법
import Image from 'next/image';
export default function Home() {
return (
<div style={{ width: '100%', height: '400px', position: 'relative' }}>
<Image
src="/hero.jpg"
alt="Hero Image"
fill // layout="fill" 대신 fill 속성 사용
style={{ objectFit: 'cover' }} // 이미지가 컨테이너를 채우는 방식
/>
</div>
);
}
Next.js 12이하 버전 : layout = "fill"
Next.js 13이상 버전 : fill
🔥 layout="fill" 사용 시 이미지 비율 보장 안되는 문제 발생 (Next.js 12 이하 버전에서)
layout="fill"은 부모 요소 중 position으로 relative, absolute, fixed 값 중 하나를 가지고 있는 요소를 기준으로 삼아 이미지 크기를 결정한다. 이런 특징을 이용하여 이미지 크기를 유동적으로 결정할 수 있다.
하지만 layout="fill"은 크기를 유동적으로 결정은 하지만 이미지 비율까지는 보장하지 못한다.
이런 layout="fill"의 단점을 보완하기 위해 사용하는 것이 objectFit이다.
objectFit props는 css의 object-fit과 동일한 역할을 하며, fill, contain 등의 값을 통해 이미지 비율을 유지할 수 있도록 해준다.
즉, next/Image에서 이미지 비율을 유지하며 반응형으로 크기를 정하기 위해서는 반드시 objectFit이라는 props를 필수로 넣어주어야 한다.
<Image
src="/example.jpg"
alt="Example Image"
layout="fill"
objectFit="cover" // 이미지 비율 유지
/>
Next.js 12 이하 버전에서는 위와 같이 사용해야 했다.
🎯 Next.js 13 이후 fill 속성과 style 변화
Next.js 13 부터는 layout 속성이 제거되었고, 대신 fill 속성을 사용하게 되면서 objectFit을 명시적으로 사용할 필요가 없어졌다.
Next.js 13부터는 styles 속성을 사용하여 직접 CSS 스타일링을 지정할 수 있게 되면서 CSS 표준 속성인 object-fit을 사용하는 것과 동일한 방식으로 스타일을 적용하게 된다. 즉, Next.js 컴포넌트에서 별도로 objectFit을 정의할 필요 없이 style={{objectFit: 'cover'}}와 같은 CSS 스타일로 설정할 수 있게 되었다.
<Image
src="/example.jpg"
alt="Example Image"
fill // layout="fill" 대신 사용
style={{ objectFit: 'cover' }} // objectFit 대신 style 사용
/>
#2. Priority
priority 속성을 사용하면 페이지의 LCP(Large Contentful Paint) 요소가 될 이미지를 우선적으로 로드할 수 있도록 지원한다.
LCP(Large Contentful Paint) : Core Web Vitals의 주요 지표 중 하나로, 사용자가 페이지를 처음 방문할 때 가장 큰 시각적 요소가 로드되기까지의 시간을 측정 => LCP 성능을 개선하면 페이지 로드 속도가 빨라지고 사용자 경험이 향상
priority 속성은 이미지 로딩 우선순위를 높여주며, Next.js는 이를 통해 브라우저가 해당 이미지를 프리로드하게끔 처리한다.
즉, <link rel="preload"> 태그를 자동으로 추가하여 이미지를 먼저 로드하고, 이로 이해 LCP 성능을 향상시킨다.
첫번째 화면에 나타나는 중요한 이미지 등에 priority 속성을 추가하는 방법도 LCP를 개선할 수 있는 방법 중 하나이다.
import Image from 'next/image'
import profilePic from '../public/me.png'
export default function Page() {
return <Image src={profilePic} alt="Picture of the author" priority />
}
[Next.js] 이미지 최적화 : next/image
프론트엔드 개발에서 중요한 최적화 요소 중 하나는 이미지 최적화이다.
이미지는 일반적인 웹사이트에서 페이지 용량의 상당 부분을 차지하며, LCP(Largest Contentful Paint) 성능에 큰 영향을 주는 요소 중 하나이다. Next.js에서는 이미지 최적화를 위해 Image 컴포넌트를 제공한다.
Image 컴포넌트는 HTML <img> 요소를 확장하여 자동 이미지 최적화 기능을 제공하며, 단 코드 몇 줄만으로 이미지를 최적화 시켜주는 내장 기능이다.
이번 포스팅에서는 Next.js에서 이미지 최적화의 필요성과 방법에 대해 작성하고자 한다.
01. 이미지 최적화의 필요성
이미지는 웹페이지에서 가장 큰 용량을 차지하는 요소 중 하나이다.
이미지를 제대로 최적화하지 않으면 페이지 로딩 속도 및 성능에 부정적인 영향을 끼치게 된다.
예를 들어, 이미지 파일 사이즈가 크고 로딩되어야 할 갯수가 많으면 이미지가 점진적으로 로딩외서 페이지가 끊겨 보이는 문제가 발생할 수 있다.
◼︎ 이미지 반응형 지원에 따른 크기 관리
웹페이지는 다양한 화면 크기와 해상도에 따라 이미지를 다른 크기로 보여주어야 한다.
만약 이미지를 동일한 크기로 제공하면, 작은 화면에서도 큰 용량의 이미지를 다운로드 해야 한다.
큰 이미지는 페이지의 초기 로딩 속도를 느리게 하며 사용자가 페이지를 열 때 불필요하게 많은 데이터를 다운로드 해야 한다.
따라서 필요에 따라 적절한 크기로 이미지를 리사이징하고, 적절한 이미지 포맷을 사용해 파일 크기를 줄여야 한다.
next/image 컴포넌트는 자동으로 srcset을 생성하여 각각의 다른 기기에 최적화된 이미지를 제공한다.
◼︎ CLS 문제 발생
이미지의 크기 정보가 없으면 로드 되는 동안 텍스트나 다른 웹페이지의 요소들이 갑자기 움직이는 CLS 문제가 발생할 수 있다.
따라서 이미지 크기를 미리 지정하거나 적절한 로드 방식을 사용하여 이를 해결해야 한다.
next/image에서는 이미지 로드 시 크기 정보를 자동으로 계산하여 레이아웃 이동을 최소화하는 기능을 제공한다.
◼︎ 초기 페이지 로딩 시간 증가 - 지연 로딩(Lazy Loading)으로 해결
앞서 언급했듯이 이미지 파일 크기는 매우 크다. 이런 이미지 파일들을 모두 로드하면 초기 페이지 로딩 시간이 매우 길어질 것이다.
이 문제를 해결하기 위해 지연 로딩을 통해 화면에 보이는 이미지만 먼저 로드하고, 나머지는 필요할 때 로드해야 한다.
next/image는 기본적으로 지연 로딩을 사용하여 페이지 성능을 최적화한다.
02. next/image
Next.js에서는 이미지 최적화를 위해 next/image를 제공한다.
next/image의 Image 컴포넌트는 다음과 같은 다양한 이미지 최적화 기능을 제공한다.
◼︎ 이미지 사이즈 최적화
next/image는 디바이스 크기 별로 srcSet을 미리 지정하여 사용자의 디바이스에 맞는 이미지를 다운로드 할 수 있도록 지원한다.
WebP, AVIF 등의 최신 이미지 포맷을 활용하여 각 기기에 최적화된 크기의 이미지를 자동으로 제공한다.
이를 적용하면 디바이스 크기에 맞는 작은 크기의 이미지를 서빙하고 jpeg 등에서 webp 포맷으로 이미지를 변환하여 큰 용량의 이미지를 작은 용량의 이미지로 제공해줄 수 있다.
◼︎ CLS 방지
예를 들어, 웹사이트에 방문하였을 때 이미지가 로드되기 전 화면에 보이던 영역의 크기보다 이미지가 로드된 후 영역의 크기가 늘어나 레이아웃이 이동되는 문제가 발생한 경험이 있을 것이다. 이처럼 이미지의 로드가 지연되는 문제로 인해 CLS가 발생한다.
next/image는 CLS를 방지하기 위해 placeholder를 제공한다.
placeholder는 이미지 로드 전에도 이미지 높이와 너비만큼의 영역을 표시해서 이미지가 로드된 후에도 레이아웃이 이동되는 것을 방지한다. placeholder는 빈 영역, blur 이미지, 커스텀하게 설정 가능하다.
◼︎ 빠른 페이지 로딩 (lazy loading)
lazy loading은 이미지를 로드하는 시점을 필요할 때까지 지연시키는 기술을 의미한다.
예를 들어, 스크린 밖에 있는 이미지들은 로딩을 지연시키고 스크린 안에 있는 이미지만을 로드해서, 불필요한 대역폭 사용을 줄이고 필요한 이미지만 빠르게 로드할 수 있도록 하는 것이다.
next/image는 브라우저에 기본적으로 지연 로딩(lazy loading)을 적용하여 viewport에 들어왔을 때만 이미지를 로드한다.
선택적으로는 작은 사이즈의 blur 이미지를 미리 로딩하여 사용자에게 더 빠른 페이지를 보여줄 수 있도록 지원한다.
03. next/image 사용하기
우선 next/image를 사용하기 위해서는 next/image를 import 해야 한다.
#1. Local Images
로컬 이미지를 사용하는 경우 이미지 파일을 import 해서 사용한다.
💡 localPatterns
Next.js 13.4.2 버전부터는 로컬 이미지의 경로를 보다 세밀하게 관리할 수 있게 해주는 localPatterns 옵션을 제공한다.
next/image는 기본적으로 /public 폴더에서 제공되는 이미지만 자동 최적화한다.
하지만 로컬 이미지 최적화를 강화하고, 더 넓은 범위의 폴더 구조에서 이미지를 사용하고 싶을 때가 있다.
이때, next.config.js 파일에 localPatterns 옵션을 사용하면 최적화할 로컬 이미지의 경로를 명확하게 지정할 수 있다.
#2. Remote Images
Remote Images를 사용하기 위해서는 src 속성에 URL 주소를 넣어주면 된다.
Next.js는 빌드 과정동안 remote files에 접근할 수 없기 때문에, width와 height가 반드시 필요하며 선택적으로는 blurDataURL을 제공해야 한다. 반면, Local Images를 사용할 때는 이미지가 로컬에 존재하기 때문에 width, height를 입력하지 않아도 Next.js는 해당 이미지에 대한 정보를 알 수 있다.
💡 remotePatterns
외부에서 임의의 이미지를 가져와 최적화할 경우, 악의적인 URL로 인해 보안 문제가 발생할 수 있다.
remotePatterns는 허용된 URL 패턴만 이미지 최적화에 사용할 수 있도록 제한한다.
특정 프로토콜, 호스트명, 경로 패턴 등을 지정하여 Next.js가 어떤 외부 이미지를 최적화할 지를 결정할 수 있다.
🎯 만약 상대 URL을 사용한다면?
만약 상대 URL을 사용해 이미지 최적화를 한다면 loader를 사용해야 한다.
상대 URL은 서버 내에서 직접 호스팅된 이미지를 가리키기 때문에 Next.js는 외부 리소스가 아닌 로컬 이미지를 최적화하도록 설정한다.
custom loader는 위와 같이 설정할 수 있다.
💡 Domains
domains 옵션도 외부의 이미지를 사용할 수 있도록 외부 도메인을 설정할 수 있다.
remotePatterns 옵션과 다르게 와일드 카드를 통한 서브 도메인을 지원하지 않고, 프로토콜, 경로 이름, 포트 번호 등을 통해 제한하는 것이 불가능하기 때문에 remotePatterns 옵션을 사용하는 것이 권장된다.
04. 이미지 최적화를 위한 추가 속성
#1. Layout
layout 속성은 image 요소를 사용했을 때 이미지가 어떤 형태로 보여주어야 하는지 정의하는 기능을 제공한다.
Next.js 13 버전 이후로는 layout="intrinsic" 값이 default로 사용된다.
하지만 intrinsic 값 외에도 상황에 맞게 아래와 같은 layout 속성을 이용할 수 있다.
💡 Next.js 13이상 버전에서 layout 속성 사용 방법
🔥 layout="fill" 사용 시 이미지 비율 보장 안되는 문제 발생 (Next.js 12 이하 버전에서)
layout="fill"은 부모 요소 중 position으로 relative, absolute, fixed 값 중 하나를 가지고 있는 요소를 기준으로 삼아 이미지 크기를 결정한다. 이런 특징을 이용하여 이미지 크기를 유동적으로 결정할 수 있다.
하지만 layout="fill"은 크기를 유동적으로 결정은 하지만 이미지 비율까지는 보장하지 못한다.
이런 layout="fill"의 단점을 보완하기 위해 사용하는 것이 objectFit이다.
objectFit props는 css의 object-fit과 동일한 역할을 하며, fill, contain 등의 값을 통해 이미지 비율을 유지할 수 있도록 해준다.
즉, next/Image에서 이미지 비율을 유지하며 반응형으로 크기를 정하기 위해서는 반드시 objectFit이라는 props를 필수로 넣어주어야 한다.
Next.js 12 이하 버전에서는 위와 같이 사용해야 했다.
🎯 Next.js 13 이후 fill 속성과 style 변화
Next.js 13 부터는 layout 속성이 제거되었고, 대신 fill 속성을 사용하게 되면서 objectFit을 명시적으로 사용할 필요가 없어졌다.
Next.js 13부터는 styles 속성을 사용하여 직접 CSS 스타일링을 지정할 수 있게 되면서 CSS 표준 속성인 object-fit을 사용하는 것과 동일한 방식으로 스타일을 적용하게 된다. 즉, Next.js 컴포넌트에서 별도로 objectFit을 정의할 필요 없이 style={{objectFit: 'cover'}}와 같은 CSS 스타일로 설정할 수 있게 되었다.
#2. Priority
priority 속성을 사용하면 페이지의 LCP(Large Contentful Paint) 요소가 될 이미지를 우선적으로 로드할 수 있도록 지원한다.
priority 속성은 이미지 로딩 우선순위를 높여주며, Next.js는 이를 통해 브라우저가 해당 이미지를 프리로드하게끔 처리한다.
즉, <link rel="preload"> 태그를 자동으로 추가하여 이미지를 먼저 로드하고, 이로 이해 LCP 성능을 향상시킨다.
첫번째 화면에 나타나는 중요한 이미지 등에 priority 속성을 추가하는 방법도 LCP를 개선할 수 있는 방법 중 하나이다.
References
https://fe-developers.kakaoent.com/2022/220714-next-image/
Next/Image를 활용한 이미지 최적화 | 카카오엔터테인먼트 FE 기술블로그
조지영(esme) 무언갈 빠르게 좋아합니다. 그래서 변화가 빠른 FE 개발이 적성에 잘 맞습니다.
fe-developers.kakaoent.com
https://nextjs.org/docs/app/building-your-application/optimizing/images
Optimizing: Images | Next.js
Optimize your images with the built-in `next/image` component.
nextjs.org
https://mayowall.tistory.com/entry/Nextjs-%EC%99%9C-%EC%83%88%EB%A1%9C%EC%9B%8C%EC%A7%84-nextImage%EB%8A%94-%EB%8D%94%EC%9D%B4%EC%83%81-objectFit%EC%9D%84-%ED%95%84%EC%9A%94%EB%A1%9C-%ED%95%98%EC%A7%80-%EC%95%8A%EA%B2%8C-%EB%90%90%EC%9D%84%EA%B9%8C
[Next.js] 왜 새로워진 next/Image는 더이상 objectFit을 필요로 하지 않게 됐을까?
목표 왜 `next/Image` v.13에서 위와 같은 태도를 취한 건지 생각해 보는 시간 가지기 예상 소요 시간 10분 Next.js는 최근 v.13 버전이 릴리즈 되면서 정말 많은 것이 바뀌었고, 그로 인해 next/Image 또한 pr
mayowall.tistory.com
https://velog.io/@go286/NextImage
Next/Image
평화롭게 회사에서 업무를 보던 중에 동료 디자이너분이 오시더니 이미지 화질이 안좋고 렌더링 속도가 되게 늦어진다 라는 말을 듣게 되었다. 사실 확인을 위해 개발하고 있던 부분을 멈추고
velog.io
'Front-End > Next.js' 카테고리의 다른 글