Next.js Google Fonts를 통한 폰트 최적화

mo__on·2024년 9월 30일
0

Next.js 프로젝트를 진행하면서 로컬 폰트를 사용하다가 해당 폰트가 Google Fonts에 등록된 것을 확인하신 경험이 있으신가요?
(일년전 제 경험담 입니다.. 머쓱 ^_^ . . )
이번 포스팅에서는 로컬 폰트와 Google Fonts를 통한 폰트 사용을 비교하고,
Next.js에서 제공하는 next/font를 사용하여 폰트 최적화하는 방법에 대해서 얘기 해보겠습니다😄
더하여 폰트 최적화의 이점과 이를 통해 프로젝트의 퍼포먼스를 우아하게 향상시키는 방법에 대해 알아보겠습니다.

Next.js에서 Google Fonts를 사용하여 폰트 최적화하기

Next.js는 웹 폰트 최적화에 도움이 되는 next/font 모듈을 제공합니다.
보통 Image 모듈과 함께 가장 먼저 접하게 되고 손쉽게 사용할 수 있는 아주 강력한 모듈입니다.
이 모듈을 사용하면 로컬 폰트와 Google Fonts를 간편하게 사용할 수 있으며,
브라우저의 렌더링 방식에 최적화된 폰트 로딩 전략을 자동으로 적용할 수 있습니다.
이를 통해 폰트 로딩 시간을 줄이고 사용자 경험을 향상시킬 수 있습니다.

예제: Google Fonts의 JUA체 적용

1. 기존: 로컬 폰트 사용하기

먼저, 로컬 폰트를 사용한 기존 코드를 살펴보겠습니다.
아래 코드는 Next.js 프로젝트에서 로컬 폰트를 적용하는 방법을 보여줍니다.


import localFont from 'next/font/local';

export const jua = localFont({
  src: './BMJUA.woff',
  display: 'swap',
  weight: '100 900',
});

로컬 폰트를 사용하는 이 방법은 폰트 파일을 직접 프로젝트에 포함하여 사용하므로 외부 요청이 필요 없습니다.
그러나 파일 크기가 커질수록 폰트 로딩 시간이 증가하여 초기 페이지 로딩 속도에 영향을 줄 수 있습니다.

2. 개선: Google Fonts 사용하기

다음은 Google Fonts를 사용하는 개선된 방식입니다.
Next.js의 next/font/google을 사용하여 Google Fonts에서 JUA체를 불러옵니다.

/font/google';

export const jua = Jua({ subsets: ['latin'], weight: ['400'] });

퍼포먼스 비교

  • 로컬 폰트 사용: 로컬 폰트를 프로젝트에 포함하여 사용 시, 폰트 파일을 직접 로드해야 합니다. 이는 초기 로딩 시 폰트 파일의 크기에 따라 성능에 영향을 미칠 수 있습니다. 로컬 폰트의 파일 크기가 크다면 첫 페이지 로딩 시간이 지연될 수 있습니다.
  • Google Fonts 사용: Google Fonts를 사용하면 CDN(Content Delivery Network)을 통해 최적화된 폰트 파일을 불러올 수 있습니다. 이를 통해 초기 로딩 시 브라우저가 폰트를 빠르게 가져올 수 있으며, 필요하지 않은 부분은 로드하지 않아 효율적입니다.

실제 프로젝트에서 폰트 최적화 전후의 성능을 측정해보았습니다.
그 결과, Google Fonts를 사용하여 폰트를 최적화할 경우 로딩 성능이 크게 개선되는 것을 확인할 수 있었습니다.

1. 로컬 폰트 사용 시

  • 폰트 파일 크기: 414KB
  • DOM 로드 시간: 780ms

로컬 폰트를 사용할 때는 폰트 파일을 프로젝트 내부에 포함하고, 초기 로딩 시 브라우저가 해당 파일을 직접 가져와야 합니다. 이 경우 폰트 파일 크기가 414KB로 상당히 큰 편이며, 이는 페이지 로딩 시 필연적으로 더 긴 시간을 유발하게 됩니다. 테스트 결과, DOM 로드 시간은 약 780ms로 나타났으며, 이는 사용자 경험에 부정적인 영향을 미칠 수 있습니다.

2. Google Fonts 사용 시

  • 최초 파일 크기: 12KB
  • 분할 로드: 폰트가 10개의 파일로 분리되어 로드됨
  • DOM 로드 시간: 350ms

Google Fonts를 사용할 경우, 폰트를 한꺼번에 로드하는 대신 필요한 폰트만 분할하여 로드합니다. 초기 로딩 시 가장 작은 단위의 폰트 파일을 먼저 가져오고, 이후 필요한 글꼴을 여러 개의 작은 파일로 분리해 로드하는 방식으로 성능을 최적화합니다. 그 결과 최초 파일 크기는 12KB에 불과하며, 분할 로딩 덕분에 브라우저가 폰트를 빠르게 로드할 수 있습니다. 이 방식으로 측정한 DOM 로드 시간은 약 350ms로, 로컬 폰트 사용 시와 비교하여 거의 절반 수준으로 단축되었습니다.

이러한 최적화는 Google Fonts의 CDN을 통한 빠른 파일 배포와 함께, 불필요한 폰트 데이터를 걸러내는 서브셋 기능을 활용한 결과입니다. 분할 로드 덕분에 브라우저가 필요한 부분만 가져와 렌더링하는 방식이 효율적으로 작동한 것을 확인할 수 있습니다.

요약하자면?

로컬 폰트는 큰 파일 크기 때문에 로딩 시간이 길어지고 사용자 경험을 저해할 수 있지만, Google Fonts를 활용하면 폰트 파일의 크기를 최소화하고 필요한 부분만 분할 로드할 수 있어 초기 로딩 시간을 크게 줄일 수 있습니다.

Tip: 보다 정확한 성능 테스트를 위해서는 Lighthouse 또는 PageSpeed Insights와 같은 도구를 사용하여 정확한 로딩 시간을 측정할 수 있습니다.

Next.js에서 Google Fonts 사용의 이점

1. 기술적 이점

  • 자동 최적화: Next.js의 next/font/google은 Google Fonts의 폰트 로딩을 최적화하여 서브셋(subset) 기능을 통해 불필요한 문자를 로드하지 않습니다. 이를 통해 폰트 파일의 크기가 줄어들어 로딩 속도가 개선됩니다.
  • 브라우저 캐싱: Google Fonts를 사용하면, 브라우저 캐시를 활용하여 폰트를 저장할 수 있습니다. 다른 웹사이트에서 동일한 폰트를 사용 중이라면, 이미 캐시된 폰트를 재사용하여 로딩 시간을 더욱 단축할 수 있습니다.
  • 자동 폰트 표시 설정: display 속성을 자동으로 설정하여 폰트가 로드되기 전까지 텍스트의 가시성을 보장합니다. 이는 페이지 렌더링을 지연시키지 않고 사용자 경험을 향상시키는 중요한 요소입니다.
  • 빌드 시 정적 에셋과 최적화: Google Fonts와 같은 외부 서비스에 대한 추가 브라우저 요청이 필요하지 않고도 폰트를 사용할 수 있게 해줍니다. 이는 CDN을 통한 글꼴 제공업체와의 데이터 공유를 제거하여 프로세스를 간소화하고 개인 정보 보호를 강화할 뿐만 아니라 전체 성능에 영향을 미칠 수 있는 로드 시간을 크게 단축합니다.
  • size-adjust 속성 자동화:

@next/font의 또 다른 핵심 기능은 CSS의 size-adjust 속성의 자동 사용 기능입니다. 이 속성은 폰트를 로딩하는 과정에서 서로 다른 폰트 크기로 인하여 발생하는 레이아웃 이동(Layout Shift)을 방지합니다. 이를 통해 사용자에게 안정적인 시각적 경험을 제공하며, 이는 사용자 유지율과 SEO 순위에 중요한 요소로 작용합니다.

2. 경험적 이점

  • 일관된 폰트 적용: Google Fonts를 사용하면 여러 프로젝트에서 일관된 폰트 스타일을 쉽게 적용할 수 있습니다. 특히 다양한 서체와 가중치를 사용할 수 있어 디자인의 유연성을 높입니다.
  • 코드 간소화: 로컬 폰트 파일을 직접 관리하지 않아도 되므로, 코드의 가독성이 향상되고 유지 보수가 편리해집니다.

간단한 예제!

Google Fonts를 사용하여 Next.js 프로젝트에서 간단한 폰트 적용 과정을 다시 한번 정리해보겠습니다.

  1. Google Fonts에서 사용할 폰트(Jua)를 Next.js에 가져옵니다.

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

export const jua = Jua({ subsets: ['latin'], weight: ['400'] });
  1. 가져온 폰트를 프로젝트에 적용합니다.

// fonts
import { jua } from '@/assets/fonts/fonts';

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      {/* <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> */}
      <body className={`${jua.className} antialiased`}>
        <NextTopLoader color="#16a34a" shadow="0 0 10px #16a34a,0 0 5px #16a34a" />
        <div id="wrap" className="min-h-screen">
          <Header />
          {children}
          <Footer />
        </div>
        <DialogProvider />
      </body>
    </html>
  );
}

이렇게 하면 Google Fonts를 통해 로드된 폰트가 프로젝트에 적용됩니다.

결론

Next.js의 next/font를 사용하여 Google Fonts로 폰트를 적용하면
로컬 폰트를 사용할 때보다 더 나은 성능을 얻을 수 있습니다.
폰트 로딩 시간을 줄이고 사용자 경험을 개선하며, 코드를 간소화할 수 있는 것이 큰 장점입니다.

추가적으로 해당 글에 대하여 궁금하신 점이 있거나, NextJs에 대해서 알아보고 싶으신 분이 있으시다면
언제든지 말씀 부탁 드리겠습니다.
오늘도 읽어주셔서 감사합니다.

참고 링크

  • Next.js Documentation - next/font
  • Google Fonts
  • Web Font Optimization - Google Developers

요약하자면?

로컬 폰트는 큰 파일 크기 때문에 로딩 시간이 길어지고 사용자 경험을 저해할 수 있지만, Google Fonts를 활용하면 폰트 파일의 크기를 최소화하고 필요한 부분만 분할 로드할 수 있어 초기 로딩 시간을 크게 줄일 수 있습니다.

profile
호기심 많은 청년

0개의 댓글