2025. 6. 4. 12:26ㆍStudy/React, next.js
이슈 복기를 위한 정리...
현재 서비스 중인 사이트는 Next.js + Nuxt + asp 로 구성되어있다.
그러다보니 인터넷이 빠른 환경에선 티가 나지 않았지만, 새롭게 Next.js 페이지로 들어오면 폰트에서 Layout Shift가 발생 중이었다.
기존엔 @font-face
로 public에 있는 폰트 파일을 로드하고 있었고, 이를 Next.js의 Local Fonts의 preload
, fallback
을 사용해서 개선하고자 하였다.
그렇게 수정 후 라이브 배포하였는데...!
Next.js 서버 트래픽이 튀는데요..?
Local Fonts
https://nextjs.org/docs/app/getting-started/fonts#local-fonts
Getting Started: Fonts | Next.js
Learn how to use fonts in Next.js
nextjs.org
@next/font includes built-in automatic self-hosting for any font file. This means you can optimally load web fonts with zero layout shift, thanks to the underlying CSS size-adjust property used.
@next/font
는 모든 폰트 파일에 빌트인 자동 셀프 호스팅 (built-in automatic self-hosting) 이 적용된다.
이는 기본 CSS 크기 조정 속성을 사용하여 layout shift 없이 웹 폰트를 최적으로 로드할 수 있게 해준다.
라고 설명하고 있다.
설명만 보면 성능 상 이점이 있어 보이는데,
왜 Next.js의 Local fonts를 적용했을 때 트래픽이 5배나 증가하였을까?
잘못된 Next.js Cache 설정
우리 서비스 특성 상 개인화 된 데이터 및 실시간으로 조회해야하는 데이터들이 대다수이며, 캐싱 관련해선 협의된 캐싱 룰에 따라 백엔드에서 전적으로 관리 중이었기 때문에 프론트에선 따로 캐싱하지 않기 위해 no-store
로 설정해준 히스토리가 있다.
(프론트에서도 캐싱한 적이 있는데 의도한 데이터가 보이지 않는다고 이슈가 올라온 적이 있다😭)
그때 next.config.js
에서 캐시설정을 asis와 같이 했었는데,
아뿔사. 모든 path에 대해서 no-store
룰이 적용되어 있다.
비단 폰트만의 문제가 아니라,
잘못된 캐시 설정으로 인해 이미지, SVG 등 다양한 곳에서 문제가 발생할 수 있는 것이었다...!
// asis
const nextConfig = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Cache-Control',
value: 'no-store',
},
],
},
];
},
...
}
그래서 아래와 같이 수정하였다.
// tobe
const nextConfig = {
async headers() {
return [
{
source: '/:path(.+\\.(?:ico|png|svg|jpg|jpeg|gif|woff|woff2)$)',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
{
source: '/:path*',
headers: [
{
key: 'Cache-Control',
value: 'no-store',
},
],
},
];
},
...
}
이렇게 next.config.js
수정과 함께
결국 Local Fonts는 삭제하고 폰트를 cdn에 올려 사용하는 것으로 최종 마무리하였다.
번외. link rel=preload 로 폰트 미리 불러오기
빠르게 가져오기 위해 link rel=preload
를 사용해주는 방법을 시도해보기도 하였다.
참고 : https://blog.banksalad.com/tech/font-preload-on-safari/
<link
rel="preload"
as="font"
type="font/woff2"
href={`${CDN_BASE_URL}/font/Pretendard-Regular.subset.woff2`}
/>
<link
rel="stylesheet"
type="text/css"
href={`${CDN_BASE_URL}/font.css`}
/>
'Study > React, next.js' 카테고리의 다른 글
[React] 관심사 분리하기 (1) | 2025.07.16 |
---|---|
[Next.js] Atomic을 지나 FSD를 거쳐서 태초마을로 오기까지 (0) | 2025.04.02 |
[Next.js] export const dynamic = 'force-dynamic' (0) | 2025.02.04 |
[Next.js] 사이드 프로젝트 초기 셋팅하기 (0) | 2024.05.27 |