728x90
반응형
들어가며: 웹 폰트 최적화가 필요한 이유
웹 개발에서 폰트는 브랜딩과 사용자 경험에 중요한 역할을 한다. 하지만 최적화되지 않은 웹 폰트는 성능 저하와 사용자 경험 악화를 초래할 수 있다. 특히 웹 바이탈 측정 요소 중 하나인 Cumulative Layout Shift (CLS)와 관련된 문제는 매우 중요하다.
Cumulative Layout Shift (CLS) 이해하기
CLS란?
- CLS는 Google의 Core Web Vitals 중 하나로, 페이지 로딩 중 발생하는 예기치 않은 레이아웃 변화를 측정하는 지표다.
CLS가 중요한 이유
- 사용자 경험
- 갑작스러운 레이아웃 변화는 사용자의 불편을 초래
- 잘못된 클릭이나 터치를 유발할 수 있음
- SEO 영향
- Google은 CLS를 검색 순위 요소로 고려
- 낮은 CLS 점수는 더 낮은 검색 순위로 이어질 수 있음
폰트 로딩이 CLS에 미치는 영향
일반적인 폰트 로딩 과정
- 초기 렌더링: 시스템 폰트 사용
- 웹 폰트 다운로드
- 폰트 교체
- 레이아웃 변화 발생
/* 전통적인 방식의 웹 폰트 적용 */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/CustomFont.woff2') format('woff2');
}
body {
font-family: 'CustomFont', system-ui, sans-serif;
}
발생하는 문제점
- FOUT (Flash of Unstyled Text)
- 시스템 폰트가 웹 폰트로 교체될 때 발생하는 깜빡임
- FOIT (Flash of Invisible Text)
- 폰트 로딩 중 텍스트가 보이지 않는 현상
- 레이아웃 변화
- 폰트 교체 시 텍스트 크기와 간격 변화로 인한 레이아웃 이동
Next.js의 폰트 최적화 솔루션
1. next/font 사용하기
- font를 빌드 타임에 다운로드
- Next.js는 지정된 커스텀 폰트를 빌드 과정에서 다운로드하고, 이를 정적 자산과 함께 호스팅 한다.
- 사용자 브라우저는 폰트를 추가로 다운로드할 필요가 없으므로 렌더링 속도가 빨라진다.
- CLS 방지
- Next.js는 폰트가 로드되기 전에 정확한 텍스트 크기와 간격 정보를 제공하여 레이아웃 이동을 방지한다.
- 이를 통해 텍스트가 초기 렌더링 시 시스템 폰트를 사용하더라도 크기가 변하지 않아 시각적 안정성이 유지된다.
import { Inter, Roboto } from 'next/font/google'
// 구글 폰트 설정
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
// 로컬 폰트 설정
const localFont = localFont({
src: './fonts/CustomFont.woff2',
display: 'swap',
})
export default function Layout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
2. 주요 최적화 기능
// 가변 폰트 설정
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter', // CSS 변수로 사용 가능
display: 'swap',
preload: true,
fallback: ['system-ui', 'arial'], // 폴백 폰트 지정
adjustFontFallback: true, // 자동 폰트 메트릭 조정
})
3. CSS에서 활용
/* 글로벌 CSS */
:root {
--font-inter: 'Inter', system-ui, sans-serif;
}
body {
font-family: var(--font-inter);
}
예시
1. 기본 설정
// app/ui/fonts.ts
import { Inter, Lusitana } from "next/font/google";
export const inter = Inter({
subsets: ["latin"],
display: "swap",
preload: true,
});
export const lusitana = Lusitana({
subsets: ["latin"],
weight: ["400", "700"],
display: "swap",
});
2. 레이아웃 적용
// app/layout.js
import "./ui/global.css";
import { inter } from "./ui/fonts";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>{children}</body>
</html>
);
}
3. 컴포넌트에서의 사용
// app/page.tsx
import { lusitana } from "./ui/fonts";
export default function Header() {
return (
<h1 className={`${lusitana.className} text-lg`}>
Test
</h1>
)
}
성능 최적화 팁
- 폰트 서브셋 활용
const inter = Inter({
subsets: ['latin'],
// 필요한 문자셋만 포함하여 파일 크기 감소
})
- 가변 폰트 사용
const inter = Inter({
variable: '--font-inter',
// 다양한 폰트 웨이트를 하나의 파일로 관리
})
- preload 설정
const inter = Inter({
preload: true,
// 중요한 폰트는 미리 로드
})
성능 측정과 모니터링
- Chrome DevTools 활용
- Performance 탭에서 폰트 로딩 시간 확인
- Network 탭에서 폰트 다운로드 상태 모니터링
- Lighthouse 점수 확인
- CLS 점수 모니터링
- 폰트 관련 성능 개선 제안 확인
결론
Next.js의 폰트 최적화 기능을 활용하면:
- CLS 문제를 효과적으로 해결 가능
- 폰트의 로딩 성능 개선
- 더 나은 사용자 경험을 제공 가능
특히 next/font의 자동 최적화 기능은 개발자가 별도의 복잡한 설정 없이도 최적의 폰트 성능을 달성할 수 있게 해준다.
728x90
반응형
'개발 공부 > Next.js' 카테고리의 다른 글
쿼리 파라미터(searchParams/useSearchParams) & 경로정보(params/usePathname ) (0) | 2025.01.03 |
---|---|
Link 컴포넌트를 이용한 네비게이션 최적화 (2) | 2025.01.02 |
Next.js Layout 이해하기 (0) | 2025.01.01 |
Next.js의 이미지 최적화 (0) | 2024.12.31 |
Next.js 15 패키지 매니저 선택하기: npm vs yarn vs pnpm (0) | 2024.12.27 |