Next.js 폰트 & 이미지 최적화 가이드

🔤 폰트 최적화

폰트 최적화가 중요한 이유

웹사이트에서 폰트는 디자인의 핵심 요소이지만, 잘못 구현하면 성능에 부정적인 영향을 미칠 수 있습니다.

🚨 Cumulative Layout Shift (CLS) 문제

CLS는 Google이 웹사이트 성능을 평가하는 핵심 지표 중 하나입니다.

문제 발생 과정:
1. 브라우저가 대체/시스템 폰트로 텍스트를 먼저 렌더링
2. 사용자 지정 폰트가 로드되면서 기존 폰트를 교체
3. 텍스트 크기, 간격 변화로 인한 레이아웃 이동 발생

⚡ Next.js의 해결책

Next.js는 next/font 모듈을 통해 폰트를 자동 최적화합니다:

  • 빌드 시점에 폰트 파일을 다운로드
  • 정적 자산과 함께 호스팅
  • 추가 네트워크 요청 없이 폰트 제공

🛠️ 기본 폰트 설정

1단계: 폰트 파일 생성

// /app/ui/fonts.ts
import { Inter } from "next/font/google";

// Inter 폰트 불러오기
export const inter = Inter({ subsets: ["latin"] });

2단계: 전역 폰트 적용

// /app/layout.tsx
import "@/app/ui/global.css";
import { inter } from "./ui/fonts";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className} antialiased`}>
        {children}
      </body>
    </html>
  );
}

💡 Tip: antialiased는 폰트를 부드럽게 렌더링하는 Tailwind CSS 클래스입니다.


🖼️ 이미지 최적화

Next.js 이미지 제공 방식

Next.js는 /public 디렉터리를 통해 정적 파일을 제공합니다. 초기 설정을 올바르게 따라했다면 다음 이미지들을 확인할 수 있습니다:

  • hero-desktop.png - 데스크톱용 이미지
  • hero-mobile.png - 모바일용 이미지

일반 HTML vs Next.js Image 컴포넌트

❌ 일반 HTML 방식의 문제점

// 권장하지 않는 방식
<img
  src="/hero.png"
  alt="Screenshots of the dashboard project"
/>

수동으로 처리해야 할 작업들:

  • 다양한 화면 크기 대응 설정
  • 디바이스별 이미지 크기 최적화
  • 레이아웃 이동 방지 작업
  • 뷰포트 밖 이미지의 Lazy Loading 구현

✅ Next.js Image 컴포넌트의 장점

Next.js <Image> 컴포넌트는 다음 기능을 자동으로 제공합니다:

  • 레이아웃 이동 자동 방지
  • 반응형 이미지 크기 조정
  • 기본 Lazy Loading
  • 최신 이미지 포맷 지원 (WebP, AVIF 등)

📱 반응형 Hero 이미지 구현

데스크톱과 모바일 환경을 모두 고려한 이미지 구현 예시입니다:

import AcmeLogo from "@/app/ui/acme-logo";
import Link from "next/link";
import Image from "next/image";

export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
        {/* <AcmeLogo /> */}
      </div>
      
      <div className="mt-4 flex grow flex-col gap-4 md:flex-row">
        <div className="flex flex-col justify-center gap-6 rounded-lg bg-gray-50 px-6 py-10 md:w-2/5 md:px-20">
          <p className="text-xl text-gray-800 md:text-3xl md:leading-normal">
            <strong>Welcome to Acme.</strong> This is the example for the{' '}
            <a href="https://nextjs.org/learn/" className="text-blue-500">
              Next.js Learn Course
            </a>
            , brought to you by Vercel.
          </p>
          
          <Link
            href="/login"
            className="flex items-center gap-5 self-start rounded-lg bg-blue-500 px-6 py-3 text-sm font-medium text-white transition-colors hover:bg-blue-400 md:text-base"
          >
            <span>Log in</span>
          </Link>
        </div>
        
        <div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
          {/* 데스크톱용 이미지 */}
          <Image
            src="/hero-desktop.png"
            width={1000}
            height={760}
            className="hidden md:block"
            alt="Screenshots of the dashboard project showing desktop and mobile versions"
          />
          
          {/* 모바일용 이미지 */}
          <Image
            src="/hero-mobile.png"
            width={560}
            height={620}
            className="block md:hidden"
            alt="Screenshot of the dashboard project showing mobile version"
          />
        </div>
      </div>
    </main>
  );
}

🔑 핵심 포인트

필수 속성

  • widthheight: 레이아웃 이동 방지를 위해 반드시 설정
  • alt: 접근성을 위한 대체 텍스트 제공

반응형 처리

  • hidden md:block: 모바일에서 숨김, 데스크톱에서 표시
  • block md:hidden: 모바일에서 표시, 데스크톱에서 숨김

📊 최적화 효과

Next.js의 폰트와 이미지 최적화를 통해 얻을 수 있는 효과:

  • 성능 향상: 빠른 로딩 속도
  • 사용자 경험 개선: 레이아웃 이동 없는 안정적인 화면
  • SEO 점수 향상: Google Core Web Vitals 개선
  • 자동화된 최적화: 개발자의 수동 작업 최소화
profile
프론트엔드 입문 개발자입니다.

0개의 댓글