본문 바로가기

Next.js

Next.js 9-3 Font Optimization

  next/font는 자동으로 글꼴(사용자 지정 글꼴 포함)을 최적화하고 개인 정보 보호 및 성능 향상을 위해 외부 네트워크 요청을 제거한다.

  next/font에는 모든 글꼴 파일에 대한 자동 자체 호스팅이 내장되어 있다. 즉, 사용된 기본 CSS 크기 조정 속성 덕분에 레이아웃 이동 없이 웹 글꼴을 최적으로 로드할 수 있다.

  이 새로운 글꼴 시스템을 사용하면 성능과 개인 정보 보호를 염두에 두고 모든 Google 글꼴을 편리하게 사용할 수 있다. CSS 및 글꼴 파일은 빌드 시 다운로드되며 나머지 정적 자산과 함께 자체 호스팅된다. 브라우저에서 Google로 요청을 보내지 않는다.

 

  • Google Fonts

  모든 Google 글꼴을 자동으로 자체 호스팅한다. 글꼴은 배포에 포함되며 배포와 동일한 도메인에서 제공된다. 브라우저에서 Google로 요청을 보내지 않는다.

  next/font/google에서 사용하려는 글꼴을 함수로 가져와서 시작하면 된다. 최상의 성능과 유연성을 위해 가변 글꼴을 사용하는 것이 좋다.

 

// app/layout.tsx

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

// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
});

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

  가변 글꼴을 사용할 수 없는 경우 두께를 지정해야 한다.

// app/layout.tsx

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

const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
  display: 'swap',
});

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

  배열을 사용하여 여려 weights and/or 스타일을 지정할 수 있다.

// app/layout.js

const roboto = Roboto({
  weight: ['400', '700'],
  style: ['normal, 'italic'],
  subsets: ['latin'],
  display: 'swap',
});

  여러 단어로 된 글꼴 이름에는 밑줄(_)을 사용하면 된다. 예를 들어 Roboto Mono는 Roboto_Mono로 사용하는 것이다.

 

  • Specifying a subset

  Google 글꼴은 자동으로 하위 집합이다. 이렇게 하면 글꼴 파일의 크기가 줄어들고 성능이 향상된다. 미리 로드할 하위 집합을 정의해야 한다. 사전 로드가 true 일 때 하위 집합을 지정하지 않으면 경고가 표시된다. 이는 함수 호출에 추가하여 수행할 수 있다.

// app/layout.tsx

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

 

  • 여러 글꼴 사용하기

  응용 프로그램에서 여러 글골을 가져와서 사용할 수 있다. 두 가지 방법을 사용할 수 있다. 첫 번째 방법은 글꼴을 내보내고 가져오고 필요한 경우 해당 className을 적용하는 유틸리티 함수를 만드는 것이다. 이렇게 하면 글꼴이 렌더링 될 때만 미리 로드된다.

// app/fonts.ts

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',
});
// app/layout.tsx

import { inter } from './fonts';

export default function Layout({ children }: { children : React.ReactNode }) {
  return (
    <html lang="en" className={inter.className}>
      <body>
        <div>{children}</div>
      </body>
    </html>
  )
}
// app/page.tsx

import { roboto_mono } from './fonts';

export default function Page() {
  return (
    <>
      <h1 className={roboto_mono.className}>My Page</h1>
    </>
  )
}

  위의 예에서 Inter는 전역으로 적용되며 Roboto Mono는 필요에 따라 가져와서 적용할 수 있다. 두 번째 방법으로 CSS 변수를 생성하고 선호하는 CSS 솔루션과 함께 사용하는 방법이 있다.

// app/layout.tsx

import { Inter, Roboto_Mono } from 'next/font/google';
import styles from './global.css';

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
  display: 'swap',
});

const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  variable: '--font-roboto-mono',
  display: 'swap',
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
      <body>
        <h1>My App</h1>
        <div>{children</div>
      </body>
    </html>
  );
}
// app/global.css

html {
  font-family: var(--font-inter);
}

h1 {
  font-family: var(--font-roboto-meno);
}

  위의 예에서 Inter는 전역적으로 적용되며 모든 <h1> 태그는 Roboto Mono로 스타일이 지정된다. 각각의 새 글꼴은 클라이언트가 다운로드해야 하는 추가 리소스이므로 여러 글꼴 사용하기는 보수적으로 사용하는 것이 좋다.

 

  • Local Fonts

  next/font/local을 가져오고 로컬 글꼴 파일의 src를 지정한다. 최상의 성능과 유연성을 위해 가변 글꼴을 사용하는 것이 좋다.

// app/layout.tsx

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>
  )
}

  단일 글꼴 모음에 대해 여러 파일을 사용하려는 경우 src는 배열일 수 있다.

const roboto = localFont({
  src: [
    {
      path: './Roboto-Regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './Roboto-Italic.woff2',
      weight: '400',
      style: 'italic',
    },
    {
      path: './Roboto-Bold.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './Roboto-BoldItalic.woff2',
      weight: '400',
      style: 'italic',
    },
  ],
});

 

  • With Tailwind CSS

  next/font는 CSS 변수를 통해 Tailwind CSS와 함께 사용할 수 있다. 아래 예에서는 next/font/google의 글꼴 Inter를 사용한다(Google 또는 Local Fonts의 모든 글꼴을 사용할 수 있음). 변수 옵션을 글꼴로 로드하여 CSS 변수 이름을 정의하고 이를 inter에 할당한다. 그런 다음 inter.variable을 사용하여 HTML 문서에 CSS 변수를 추가한다.

// app/layout.tsx

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

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-inter',
});

const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-roboto-mono',
});

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

  마지막으로 Tailwind CSS 구성에 CSS 변수를 추가한다.

// tailwind.config.js

/** @type { import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js, ts, jsx, tsx}',
    './components/**/*.{js, ts, jsx, tsx}',
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-inter)'],
        mono: ['var(--font-roboto-mono)'],
      },
    },
  },
  plugin: [],
};

  이제 font-sans 및 font-mono 유틸리티 클래스를 사용하여 요소에 글꼴을 적용할 수 있다.

 

  • 사전 로드 (Preloading)

  사이트의 페이지에서 글꼴 기능이 호출되면 전역적으로 사용할 수 없으며 모든 경로에 미리 로드된다. 오히려 글꼴은 사용되는 파일 유형에 따라 관련 경로에만 사전 로드된다.

  고유한 페이지인 경우 해당 페이지의 고유한 경로에 미리 로드된다. 레이아웃인 경우 레이아웃에 의해 래핑 된 모든 경로에 미리 로드된다. 루트 레이아웃인 경우 모든 경우에 미리 로드된다.

 

  • 글꼴 재사용

  localFont 또는 Google 글꼴 함수를 호출할 때마다 해당 글꼴은 애플리케이션에서 하나의 인스턴스로 호스팅 된다. 따라서 여러 파일에서 동일한 글꼴 기능을 로드하면 동일한 글꼴의 여러 인스턴스가 호스팅 된다. 이 경우 다음을 수행하는 것이 좋다.

  1. 하나의 공유 파일에서 폰트 로더 기능 호출
  2. 상수로 내보내기
  3. 이 글꼴을 사용하려는 가 파일에서 상수를 가져오기