Next.js 프로젝트를 진행하면서 로컬 폰트를 사용하다가 해당 폰트가 Google Fonts에 등록된 것을 확인하신 경험이 있으신가요?
(일년전 제 경험담 입니다.. 머쓱 ^_^ . . )
이번 포스팅에서는 로컬 폰트와 Google Fonts를 통한 폰트 사용을 비교하고,
Next.js에서 제공하는 next/font
를 사용하여 폰트 최적화하는 방법에 대해서 얘기 해보겠습니다😄
더하여 폰트 최적화의 이점과 이를 통해 프로젝트의 퍼포먼스를 우아하게 향상시키는 방법에 대해 알아보겠습니다.
Next.js는 웹 폰트 최적화에 도움이 되는 next/font
모듈을 제공합니다.
보통 Image 모듈과 함께 가장 먼저 접하게 되고 손쉽게 사용할 수 있는 아주 강력한 모듈입니다.
이 모듈을 사용하면 로컬 폰트와 Google Fonts를 간편하게 사용할 수 있으며,
브라우저의 렌더링 방식에 최적화된 폰트 로딩 전략을 자동으로 적용할 수 있습니다.
이를 통해 폰트 로딩 시간을 줄이고 사용자 경험을 향상시킬 수 있습니다.
먼저, 로컬 폰트를 사용한 기존 코드를 살펴보겠습니다.
아래 코드는 Next.js 프로젝트에서 로컬 폰트를 적용하는 방법을 보여줍니다.
import localFont from 'next/font/local';
export const jua = localFont({
src: './BMJUA.woff',
display: 'swap',
weight: '100 900',
});
로컬 폰트를 사용하는 이 방법은 폰트 파일을 직접 프로젝트에 포함하여 사용하므로 외부 요청이 필요 없습니다.
그러나 파일 크기가 커질수록 폰트 로딩 시간이 증가하여 초기 페이지 로딩 속도에 영향을 줄 수 있습니다.
다음은 Google Fonts를 사용하는 개선된 방식입니다.
Next.js의 next/font/google
을 사용하여 Google Fonts에서 JUA체를 불러옵니다.
/font/google';
export const jua = Jua({ subsets: ['latin'], weight: ['400'] });
실제 프로젝트에서 폰트 최적화 전후의 성능을 측정해보았습니다.
그 결과, Google Fonts를 사용하여 폰트를 최적화할 경우 로딩 성능이 크게 개선되는 것을 확인할 수 있었습니다.
로컬 폰트를 사용할 때는 폰트 파일을 프로젝트 내부에 포함하고, 초기 로딩 시 브라우저가 해당 파일을 직접 가져와야 합니다. 이 경우 폰트 파일 크기가 414KB로 상당히 큰 편이며, 이는 페이지 로딩 시 필연적으로 더 긴 시간을 유발하게 됩니다. 테스트 결과, DOM 로드 시간은 약 780ms로 나타났으며, 이는 사용자 경험에 부정적인 영향을 미칠 수 있습니다.
Google Fonts를 사용할 경우, 폰트를 한꺼번에 로드하는 대신 필요한 폰트만 분할하여 로드합니다. 초기 로딩 시 가장 작은 단위의 폰트 파일을 먼저 가져오고, 이후 필요한 글꼴을 여러 개의 작은 파일로 분리해 로드하는 방식으로 성능을 최적화합니다. 그 결과 최초 파일 크기는 12KB에 불과하며, 분할 로딩 덕분에 브라우저가 폰트를 빠르게 로드할 수 있습니다. 이 방식으로 측정한 DOM 로드 시간은 약 350ms로, 로컬 폰트 사용 시와 비교하여 거의 절반 수준으로 단축되었습니다.
이러한 최적화는 Google Fonts의 CDN을 통한 빠른 파일 배포와 함께, 불필요한 폰트 데이터를 걸러내는 서브셋 기능을 활용한 결과입니다. 분할 로드 덕분에 브라우저가 필요한 부분만 가져와 렌더링하는 방식이 효율적으로 작동한 것을 확인할 수 있습니다.
로컬 폰트는 큰 파일 크기 때문에 로딩 시간이 길어지고 사용자 경험을 저해할 수 있지만, Google Fonts를 활용하면 폰트 파일의 크기를 최소화하고 필요한 부분만 분할 로드할 수 있어 초기 로딩 시간을 크게 줄일 수 있습니다.
Tip: 보다 정확한 성능 테스트를 위해서는 Lighthouse 또는 PageSpeed Insights와 같은 도구를 사용하여 정확한 로딩 시간을 측정할 수 있습니다.
next/font/google
은 Google Fonts의 폰트 로딩을 최적화하여 서브셋(subset) 기능을 통해 불필요한 문자를 로드하지 않습니다. 이를 통해 폰트 파일의 크기가 줄어들어 로딩 속도가 개선됩니다.display
속성을 자동으로 설정하여 폰트가 로드되기 전까지 텍스트의 가시성을 보장합니다. 이는 페이지 렌더링을 지연시키지 않고 사용자 경험을 향상시키는 중요한 요소입니다.@next/font
의 또 다른 핵심 기능은 CSS의 size-adjust
속성의 자동 사용 기능입니다. 이 속성은 폰트를 로딩하는 과정에서 서로 다른 폰트 크기로 인하여 발생하는 레이아웃 이동(Layout Shift)을 방지합니다. 이를 통해 사용자에게 안정적인 시각적 경험을 제공하며, 이는 사용자 유지율과 SEO 순위에 중요한 요소로 작용합니다.
Google Fonts를 사용하여 Next.js 프로젝트에서 간단한 폰트 적용 과정을 다시 한번 정리해보겠습니다.
Jua
)를 Next.js에 가져옵니다.
import { Jua } from 'next/font/google';
export const jua = Jua({ subsets: ['latin'], weight: ['400'] });
// 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에 대해서 알아보고 싶으신 분이 있으시다면
언제든지 말씀 부탁 드리겠습니다.
오늘도 읽어주셔서 감사합니다.
로컬 폰트는 큰 파일 크기 때문에 로딩 시간이 길어지고 사용자 경험을 저해할 수 있지만, Google Fonts를 활용하면 폰트 파일의 크기를 최소화하고 필요한 부분만 분할 로드할 수 있어 초기 로딩 시간을 크게 줄일 수 있습니다.