[Next.js] Asset 최적화 방법 (img, font, script)
Next.js에서 img, font, script 최적화해서 사용하는 방법을 알아보자
웹사이트의 성능을 높이는 중요한 요소 중 하나는 애셋(asset) 최적화다. Next.js
는 이미지, 폰트, 스크립트 파일을 효율적으로 관리하고 최적화하는 기능을 제공하여 사용자 경험을 개선할 수 있게 해준다. 어떤 방법이 있는지 알아보자!
Next/Image를 이용해 이미지를 최적화 하자
이미지는 일반적인 웹사이트 페이지 무게의 아주 큰 부분을 차지하며, 웹사이트의 LCP(Largest Contentful Paint) 성능에 큰 영향을 미친다. 하지만 Next.js
는 자동으로 이미지 크기를 최적화 해주는 컴포넌트인 Image
컴포넌트를 제공해준다.
1-1) Image 컴포넌트 설명
공식문서에서의 설명은 아래와 같다.
- 크기 최적화: 각 기기에 맞는 크기의 이미지를 자동으로 제공하고, WebP 및 AVIF와 같은 최신 이미지 형식을 사용합니다.
- 시각적 안정성: 이미지가 로딩 될 때 레이아웃 이동을 자동으로 방지합니다.
- 빠른 페이지 로드: 네이티브 브라우저 지연 로딩을 사용하여 이미지가 뷰포트에 들어올 때만 로드 됩니다. 블러업 플레이스 홀더를 옵션으로 사용 가능.
- 자산 유연성: 원격 서버에 저장된 이미지도 포함하여 필요에 따라 이미지 크기 조정.
1-2) Image 컴포넌트 사용 방법
이전에 강의를 들을 때 코드 스니펫을 복붙하며 따라가던 중 Image 에러가 노출되어 수정한 경험이 있다. 사용 방법은 간단하며, Next.js
에서도 img태그를 쓸 때 “님 왜 그거 씀?” 이런 식으로 안내를 해준다.
- 궁금하면 보십셔: Image 컴포넌트를 안쓰면 어케되는지 글을 작성해봄
// 사용 방법
import Image from "next/image"; // 임폴트하셈
return (
{/* 사용하셈 */}
<Image
className="rounded-sm object-scale-down"
width={80}
src={product.images}
alt={product.title}
/>
)
1-3) 로컬 이미지 사용
로컬이미지는 리액트에서 썻던 방식과 똑같음
import Image from 'next/image'
import profilePic from './me.png'
export default function Page() {
return (
<Image
src={profilePic}
alt="Picture of the author"
// width={500} 자동 제공
// height={500} 자동 제공
// blurDataURL="data:..." 자동 제공
// placeholder="blur" // 로딩 중 블러업 옵션
/>
)
}
1-4) 네트워크 이미지 사용
주소값을 통해 불러오는 네트워크 이미지도 로컬 이미지와 크게 다르지 않음, 하지만 보안에 안전한 프로젝트를 위해 한가지 설정을 해줘야함
-
next.config.js
설정- next.config.js 파일에 지원되는 URL 패턴을 정의하여 안전하게 이미지 최적화
const nextConfig = {
reactStrictMode: false,
images: {
remotePatterns: [
{
protocol: "https",
hostname: "fakestoreapi.com", // url
pathname: "/**", // 전체
},
],
formats: ["image/avif", "image/webp"], // 자동으로 포멧 변환
},
};
네트워크 이미지 사용
import Image from 'next/image'
export default function Page() {
return (
<Image
src="<network-image>"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
1-5) 테스트
- Next.js에서는
public
폴더를 사용하여 정적 파일을 쉽게 제공할 수 있음. -
public
폴더 내의 파일은 기본 URL(/
)을 기준으로 참조할 수 있음.
import Image from 'next/image'
import Logo from "/public/assets/logo.png";
<Image height={40} src={Logo} alt="logo"></Image>
Font Optimization
- Google Fonts를 자동으로 셀프 호스팅할 수 있음.
- 폰트는 배포 시 포함되어 동일한 도메인에서 제공함.
2-1) 기본 사용법
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
2-2) 멀티 폰트 사용
여러 폰트를 사용해야 할 때는 폰트를 내보내고 필요한 곳에서 가져와서 사용하면 됨
import { Inter, Roboto_Mono } from 'next/font/google'
export const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
})
import { inter } from './fonts'
export default function Layout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>
<div>{children}</div>
</body>
</html>
)
}
2-3) 로컬 폰트 사용
import localFont from 'next/font/local'
// Font files can be colocated inside of `app`
const myFont = localFont({
src: './my-font.woff2',
display: 'swap',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={myFont.className}>
<body>{children}</body>
</html>
)
}
Script
`
3-1) 기본 사용법
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
<Script src="https://example.com/script.js" />
</html>
)
3-2) 세부 조정법
-
beforeInteractive
: Next.js 코드 및 페이지 하이드레이션 전에 스크립트 로드 -
afterInteractive
: (기본값) 페이지 하이드레이션 후 스크립트 로드 -
lazyOnload
: 브라우저 유휴 시간에 스크립트 로드 -
worker
: (실험적) 웹 워커에서 스크립트 로드
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}
마무리
Next.js를 사용하여 애셋 최적화를 적용하면 웹사이트 성능을 크게 향상시킬 수 있다. 이미지, 폰트, 스크립트는 페이지 로딩 시간과 사용자 경험에 직접적인 영향을 미치므로, 각각의 최적화 전략을 잘 적용해 봐야겠다.