Next의 이미지 최적화
Next는 자동으로 이미지 크기를 최적화해주는 이미지 컴포넌트(Image)를 제공한다.
Image 태그의 기능
1) 크기 최적화
- 각 기기에 맞는 크기의 이미지를 자동으로 제공하고, WebP 및 AVIF와 같은 최신 이미지 형식을 사용
// next.config.js 설정 추가
module.exports = {
images: {
// ...
formats: ['image/avif', 'image/webp'],
},
}
2) 시각적 안정성
- 이미지가 로딩도리 때 레이아웃 이동을 자동으로 방지
3) 빠른 페이지 로드
- 네이티브 브라우저 지연 로딩을 사용하여 이미지가 뷰포트에 들어올 때만 로드됨
- 블러업 플레이스 홀더를 옵션으로 사용 가능
4) 자산 유연성
- 원격 서버에 저장된 이미지도 포함하여 필요에 따라 이미지 조정
사용법
1) 로컬이미지
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" // 로딩 중 블러업 옵션
/>
)
}
2) 원격, 네트워크 이미지
import Image from 'next/image'
export default function Page() {
return (
<Image
src="<network-image>"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
// next.config.js 설정
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
images: {
remotePatterns: [
{
protocol: "https",
hostname: "fakestoreapi.com",
pathname: "/**",
},
],
formats: ["image/avif", "image/webp"],
},
};
최적화 원리
1) lazy loading
- 뷰포트에 노출되는 이미지만 로드하여 페이지 로드 속도를 개선
- js의 경우 따로 구현하지 않는 이상 페이지의 전체 데이터를 모두 로드
2) 이미지 사이즈 최적화
- 최초 요청시 Next.js 서버에서 이미지를 용량이 작은 WebP, AVIF 포맷으로 변환
Metadata를 이용한 SEO 최적화
정적 메타데이터
// layout.tsx | page.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}
동적 메타데이터
generateMetadata 함수를 활용한다!
// app/products/[id]/page.tsx
import type { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
export async function generateMetadata(
{ params, searchParams }: Props,
): Promise<Metadata> {
// 경로 매개변수 읽기
const id = params.id
// 데이터 가져오기
const product = await fetch(`https://.../${id}`).then((res) => res.json())
return {
title: product.title,
}
}
export default function Page({ params, searchParams }: Props) {}
필드 상속
// app/layout.js
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}
// app/about/page.js
export const metadata = {
title: 'About',
}
// 출력:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme is a..." />
app/about/page.js가 openGraph 메타데이터를 설정하지 않기 때문에 app/layout.js의 모든 openGraph 필드는 app/about/page.js에 상속된다.
Static Asset
넥스트에서는 정적 데이터를 public 폴더에서 쉽게 관리할 수 있다.
import Image from 'next/image'
import Logo from "/public/assets/logo.png";
<Image height={40} src={Logo} alt="logo"></Image>
Font 최적화
next/font는 모든 폰트 파일에 대해 자동으로 셀프 호스팅을 제공한다.
레이아웃 시프팅 없이 최적의 방식으로 웹 폰트를 로드할 수 있도록 도와준다.
구글 폰트 사용하기
next/font/google에서 사용할 폰트를 가져와 함수로 사용한다.
import { Inter } from 'next/font/google'
const inter = Inter({
weight: '400', // font weight 지정 가능
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
Multiple Fonts 사용하기
여러 폰트를 사용할 때는 폰트를 내보내고 필요한 곳에서 가져와 사용한다.
// fonts 파일에서 폰트를 설정해 내보낸다.
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>
)
}
Local Fonts 사용하기
next/font/local로 로컬 폰트 변수를 생성하여 사용한다.
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
next/script를 사용해 스크립틀을 최적화할 수 있다.
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>
)
}
스크립트 로딩 전략
세부 로딩 전략을 조정할 수 있다.
1) beforeInteractive: Next.js 코드 및 페이지 하이드레이션 전에 스크립트를 먼저 로드
2) afterInteractive: (기본값) 페이지 하이드레이션 후 스크립트를 로드
3) lazyOnload: 브라우저 유휴 시간에 스크립트 로드
4) worker: 웹 워커에서 스크립트 로드 (실험적)
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}
'Next.js' 카테고리의 다른 글
[Next.js] Caching (1) | 2024.09.28 |
---|---|
[Next.js] Router Handler & Server Action (0) | 2024.09.27 |
[Next.js] Error UI, Error Handling (0) | 2024.09.27 |
[Next.js] Suspense, Loading UI, Streaming SSR (0) | 2024.09.27 |
[Next.js] Server Component & Client Component, 렌더링 방식 (2) | 2024.09.26 |