[ Optimizing ] Fonts

차차·2023년 5월 23일
0

Next Docs

목록 보기
26/34
post-thumbnail

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

next/font에는 모든 폰트 파일에 대한 내장 자동 셀프 호스팅 기능이 포함되어 있다. 이는 사용되는 기본 CSS size-adjust 속성 덕분에 웹 폰트를 최적으로 로드하여 레이아웃 시프트를 제로로 만들 수 있다.

이 새로운 폰트 시스템을 사용하면 Google Fonts를 효율성과 개인 정보 보호를 고려하여 편리하게 사용할 수도 있다. 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({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

변수 폰트를 사용할 수 없는 경우, weight를 지정해야 한다.

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

배열을 사용하여 여러 weight/또는 스타일을 지정할 수 있다.

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

여러 단어로 된 폰트 이름에는 밑줄 (_)을 사용한다. 예: Roboto Mono는 Roboto_Mono로 가져와야 한다.


서브셋 지정(Specifying a subset)

Google 폰트는 자동으로 서브셋으로 처리된다. 이렇게 하면 폰트 파일의 크기가 줄어들고 성능이 향상된다. 미리로드할 서브셋을 정의해야 한다. preloadtrue인 상태에서 어떤 서브셋도 지정하지 않으면 경고가 발생한다.

이를 함수 호출에 추가하여 수행할 수 있다.

// app/layout.tsx

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

여러 폰트 사용하기(Using Multiple Fonts)

애플리케이션에서 여러 폰트를 가져와 사용할 수 있다. 두 가지 접근 방식이 있다.

첫 번째 접근 방식은 유틸리티 함수를 생성하여 폰트를 내보내고 가져와 필요한 곳에 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 솔루션과 함께 사용할 수도 있다.

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

위의 예제에서는 Inter가 전역으로 적용되고, <h1> 태그에는 Roboto Mono로 스타일이 지정된다.

클라이언트가 다운로드해야 하는 추가 리소스인 각 새로운 폰트마다 신중하게 여러 폰트를 사용하는 것을 권장한다.



로컬 폰트

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: '700',
      style: 'normal',
    },
    {
      path: './Roboto-BoldItalic.woff2',
      weight: '700',
      style: 'italic',
    },
  ],
});


Tailwind CSS와 사용

next/fontCSS 변수를 통해 Tailwind CSS와 함께 사용할 수 있다.


아래 예제에서는 next/font/google에서 Inter 폰트를 사용한다. (Google이나 로컬 폰트에서 원하는 폰트를 사용할 수 있다). 변수 옵션을 사용하여 폰트를 로드하고 CSS 변수 이름을 정의하고 inter에 할당한다. 그런 다음, inter.variable을 사용하여 CSS 변수를 HTML 문서에 추가한다.

// 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 configCSS 변수를 추가한다.

// 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)'],
      },
    },
  },
  plugins: [],
};

이제 font-sansfont-mono 유틸리티 클래스를 사용하여 폰트를 요소에 적용할 수 있다.



사전 로드(Preloading)

사이트의 페이지에서 폰트 함수를 호출할 때, 해당 폰트는 전역으로 사용 가능하고 모든 경로에 사전로드되는 것은 아니다. 대신, 사용된 파일의 종류에 따라 관련 경로에만 폰트가 사전로드된다.

  • 고유한 페이지인 경우, 해당 페이지의 고유 경로에 사전로드된다.

  • 레이아웃인 경우, 해당 레이아웃으로 래핑된 모든 경로에 사전로드된다.

  • 루트 레이아웃인 경우, 모든 경로에 사전로드된다.



폰트 재사용(Reusing Fonts)

localFont 또는 Google 폰트 함수를 호출할 때마다 해당 폰트는 애플리케이션 내에서 하나의 인스턴스로 호스팅된다. 따라서 동일한 폰트 함수를 여러 파일에서 로드하는 경우, 동일한 폰트의 여러 인스턴스가 호스팅된다.

이 경우 다음을 권장한다.

  • 공유 파일에서 폰트 로더 함수를 호출한다.

  • 상수로 export 한다.

  • 해당 폰트를 사용하려는 각 파일에서 해당 상수를 import 한다.



[ 출처 ]
https://nextjs.org/docs/app/building-your-application/optimizing/fonts

profile
나는야 프린이

0개의 댓글