Chapter 3. Optimizing Fonts and Images

제3장

글꼴 및 이미지 최적화

이전 장에서는 Next.js 애플리케이션을 스타일링하는 방법에 대해 배웠습니다. 사용자 정의 글꼴 및 히어로 이미지를 추가하여 홈 페이지 작업을 계속해 보겠습니다.

이 장에서는...

다음과 같은 주제들을 다룰 예정입니다.

  • next/font를 사용하여 사용자 정의 글꼴 추가하는 방법

  • next/image를 사용하여 이미지 추가하는 방법

  • Next.js에서 글꼴과 이미지가 어떻게 최적화되는지


왜 글꼴을 최적화해야 할까요?

글꼴은 웹사이트 디자인에서 중요한 역할을 합니다. 그러나 프로젝트에서 사용자 정의 글꼴을 사용하면 글꼴 파일을 가져오고 로드해야 하므로 성능에 영향을 미칠 수 있습니다.

Cumulative Layout Shift는 Google이 성능 및 사용자 경험을 평가하는 데 사용하는 측정항목 중 하나입니다. 글꼴을 사용하면, 브라우저가 처음에 대체 또는 시스템 글꼴로 텍스트를 렌더링하고 로드된 후에 사용자 정의 글꼴로 교체될 때 레이아웃 시프트가 발생합니다. 이 교체로 인해 텍스트 크기, 간격 또는 레이아웃이 변경되어 주변 요소가 이동할 수 있습니다.

Next.js는 next/font 모듈을 사용할 때 애플리케이션에서 글꼴을 자동으로 최적화합니다. 이 모듈을 사용하면 글꼴 파일을 빌드 시 다운로드하고 다른 정적 애셋과 함께 호스팅합니다. 이렇게 하면 사용자가 애플리케이션을 방문할 때 글꼴에 대한 추가 네트워크 요청이 없으므로 성능에 영향을 미치지 않습니다.

퀴즈 시간입니다!

지금까지 배운 내용을 테스트해 보세요.

Next.js는 글꼴을 어떻게 최적화하나요?

  • A: 성능을 향상시키기 위해 추가적인 네트워크 요청을 발생시킵니다.

  • B: 모든 사용자 정의 글꼴을 비활성화합니다.

  • C: 모든 글꼴을 런타임에 미리로드합니다.

  • D: 글꼴 파일을 다른 정적 애셋과 함께 호스팅하여 추가적인 네트워크 요청이 없도록 합니다.

정답 확인

D: 글꼴 파일을 다른 정적 애셋과 함께 호스팅하여 추가적인 네트워크 요청이 없도록 합니다.


주요 글꼴 추가하기

이제 애플리케이션에 Google 글꼴을 추가하여 이 작업이 어떻게 수행되는지 살펴보겠습니다!

/app/ui 폴더에서 fonts.ts라는 새 파일을 만들어서 애플리케이션 전체에서 사용될 글꼴을 관리할 것입니다.

/app/ui/fonts.ts

import { Inter } from 'next/font/google';

그런 다음, next/font/google 모듈에서 Inter 글꼴을 가져옵니다. 이것이 주요 글꼴이 될 것입니다.

/app/ui/fonts.ts

import { Inter } from 'next/font/google';

export const inter = Inter({ subsets: ['latin'] });

마지막으로, /app/layout.tsx에서 <body> 요소에 글꼴을 추가합니다.

/app/layout.tsx

import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';

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

<body> 요소에 Inter를 추가함으로써 글꼴이 애플리케이션 전체에 적용됩니다. 여기서는 Tailwind의 antialiased 클래스도 추가했습니다. 이 클래스를 사용하는 것이 필수는 아니지만 글꼴을 부드럽게 만들어줍니다.

브라우저로 이동하여 개발자 도구를 열고 body 요소를 선택하십시오. 이제 InterInter_Fallback이 스타일 아래에 적용된 것을 확인할 수 있습니다. 또한 애플리케이션의 특정 요소에도 글꼴을 추가할 수 있습니다.


실습: 보조 글꼴 추가하기

이제 당신의 차례입니다! fonts.ts 파일에서 Lusitana라는 보조 글꼴을 가져와 /app/page.tsx 파일의 <p> 요소에 전달하십시오. 이전과 마찬가지로 서브셋을 지정하는 것 외에도 글꼴 두께를 지정해야합니다.

준비가 되면 아래의 코드 스니펫을 확장하여 정답을 확인하세요.

힌트:

  • 글꼴에 어떤 두께 옵션을 전달해야 하는지 확실하지 않다면 코드 편집기에서 TypeScript 오류를 확인하세요.

  • Google Fonts 웹사이트를 방문하여 Lusitana를 검색하여 사용 가능한 옵션을 확인하세요.

  • 여러 글꼴 추가전체 옵션 목록에 대한 문서를 참조하세요.

솔루션 보기

/app/ui/fonts.ts

import { Inter, Lusitana } from 'next/font/google';

export const inter = Inter({ subsets: ['latin'] });

export const lusitana = Lusitana({
  weight: ['400', '700'],
  subsets: ['latin'],
});

/app/page.tsx

import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import { lusitana } from '@/app/ui/fonts';

export default function Page() {
  return (
    // ...
    <p
      className={`${lusitana.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>
    // ...
  );
}

마지막으로 <AcmeLogo /> 컴포넌트도 Lusitana를 사용합니다. 오류를 방지하기 위해 주석 처리되어 있었으나, 이제 주석 처리를 해제할 수 있습니다.

/app/page.tsx

// ...

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>
    </main>
  );
}

좋습니다! 애플리케이션에 두 개의 사용자 정의 글꼴이 추가되었습니다! 이제 홈 페이지에 히어로 이미지를 추가해 보겠습니다.


이미지 최적화는 왜 필요한가요?

Next.js는 이미지와 같은 정적 자산을 최상위 /public 폴더 아래에서 제공할 수 있습니다. /public 내부의 파일은 애플리케이션에서 참조할 수 있습니다.

/public 폴더 내부를 살펴보면 두 개의 이미지, hero-desktop.pnghero-mobile.png가 있습니다. 이 두 이미지는 완전히 다르며 사용자의 기기가 데스크톱인지 모바일인지에 따라 표시됩니다.

일반적인 HTML에서는 이미지를 다음과 같이 추가합니다.

<img
  src="/hero.png"
  alt="데스크톱 및 모바일 버전의 대시보드 프로젝트 스크린샷"
/>

그러나 이렇게 하면 다음을 수동으로 수행해야 합니다.

  • 이미지가 다양한 화면 크기에 반응적으로 표시되도록 보장합니다.

  • 다양한 기기에 대한 이미지 크기를 지정합니다.

  • 이미지가 로드됨에 따라 레이아웃 시프트를 방지합니다.

  • 뷰포트 외부에 있는 이미지를 지연로드합니다.

이미지 최적화는 웹 개발에서 큰 주제이며 그 자체로 전문 분야로 간주될 수 있습니다. 이러한 최적화를 수동으로 구현하는 대신 next/image 컴포넌트를 사용하여 이미지를 자동으로 최적화할 수 있습니다.


<Image> 컴포넌트

<Image> 컴포넌트는 HTML <img> 태그의 확장이며 다음과 같은 자동 이미지 최적화 기능을 제공합니다.

  • 이미지가 로드될 때 자동으로 레이아웃 시프트 방지.

  • 뷰포트에 들어올 때 이미지 크기를 조절하여 작은 뷰포트 기기로 큰 이미지를 전송하지 않도록 함.

  • 기본적으로 이미지를 지연로드 (이미지가 뷰포트에 진입할 때 로드).

  • 브라우저가 지원하는 경우 WebPAVIF와 같은 현대적인 포맷으로 이미지 제공.


데스크톱 히어로 이미지 추가

<Image> 컴포넌트를 사용해보겠습니다.

/app/page.tsx 파일 안에, next/image에서 컴포넌트를 가져와 주석 아래에 이미지를 추가하세요:

/app/page.tsx

import AcmeLogo from '@/app/ui/acme-logo';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';

export default function Page() {
  return (
    // ...

    <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="데스크톱 및 모바일 버전을 보여주는 대시보드 프로젝트의 스크린샷"
      />
    </div>
    //...
  );
}

여기서 이미지의 width1000으로, height760으로 설정하고 있습니다. 레이아웃 이동을 방지하기 위해 이미지의 widthheight를 소스 이미지와 동일한 종횡비로 설정하는 것이 좋습니다.

또한, 모바일 화면에서 이미지를 제거하기 위해 hidden 클래스를, 데스크톱 화면에서 이미지를 보여주기 위해 md:block 클래스를 사용하고 있습니다.

이제 홈페이지는 다음과 같아야 합니다:


연습: 모바일 히어로 이미지 추가

이제 여러분의 차례입니다! 방금 추가한 이미지 아래에 mobile-hero.png에 대한 또 다른 <Image> 컴포넌트를 추가하세요.

  • 이미지의 width560이고 height620 픽셀로 설정하세요.

  • 모바일 화면에서 보이고 데스크톱에서는 숨겨져야 합니다 - 데스크톱 및 모바일 이미지가 올바르게 교체되었는지 확인하려면 개발 도구를 사용하세요.

준비가 되었으면 아래의 코드 스니펫을 확장하여 정답을 확인하세요.

솔루션 보기

/app/page.tsx

import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';

export default function Page() {
  return (
    // ...
    <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="데스크톱 및 모바일 버전을 보여주는 대시보드 프로젝트의 스크린샷"
      />
      <Image
        src="/hero-mobile.png"
        width={560}
        height={620}
        className="block md:hidden"
        alt="모바일 버전을 보여주는 대시보드 프로젝트의 스크린샷"
      />
    </div>
    //...
  );
}

좋습니다! 이제 홈페이지에는 커스텀 폰트와 히어로 이미지가 있습니다.

퀴즈 시간입니다!

여러분이 방금 배운 내용을 테스트하고 학습한 내용을 확인하세요.

참/거짓: 크기를 지정하지 않은 이미지와 웹 폰트는 레이아웃 이동의 일반적인 원인입니다.

  • A: 참

  • B: 거짓

정답 확인

A: 참


추천하는 읽을거리

이러한 주제에 대해 더 알아보려면 원격 이미지 최적화 및 로컬 글꼴 파일 사용과 관련된 추가 정보를 확인하세요. 글꼴 및 이미지에 대해 더 깊게 파고들고 싶다면 다음을 참고하세요:

Last updated