上节我们学习了图片优化,本节来聊聊字体优化。字体对网页的视觉效果和加载速度都有很大影响,Next.js 提供了优秀的字体优化方案。
字体优化概述
Next.js 13+ 内置 next/font,提供:
- 自动字体优化 - 自动托管和优化字体文件
- 零布局偏移 - 使用 CSS size-adjust
- 隐私友好 - 不向 Google 发送请求
- 自动自托管 - 字体文件与构建一起部署
使用 Google Fonts
基本用法
// app/layout.tsx
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN" className={inter.className}>
<body>{children}</body>
</html>
)
}
多个字体
import { Inter, Playfair_Display } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
})
const playfair = Playfair_Display({
subsets: ['latin'],
variable: '--font-playfair',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body className={`${inter.variable} ${playfair.variable}`}>
{children}
</body>
</html>
)
}
使用本地字体
基本 Local Font
import localFont from 'next/font/local'
const myFont = localFont({
src: './my-font.woff2',
display: 'swap',
})
export default function Page() {
return <div className={myFont.className}>内容</div>
}
多字重本地字体
import localFont from 'next/font/local'
const myFont = localFont({
src: [
{
path: './my-font-regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './my-font-bold.woff2',
weight: '700',
style: 'normal',
},
],
display: 'swap',
})
字体显示策略
font-display 属性控制字体加载时的行为:
const inter = Inter({
subsets: ['latin'],
display: 'swap', // 可选值:auto, block, swap, fallback, optional
})
不同策略的说明:
- auto - 浏览器默认行为
- block - 短暂隐藏文本,直到字体加载
- swap - 立即显示后备字体,字体加载后替换
- fallback - 短暂隐藏文本,超时后使用后备字体
- optional - 短暂隐藏文本,超时后使用后备字体(不会替换)
响应式字体
使用 CSS 变量实现响应式字体:
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body className={inter.variable}>
{children}
</body>
</html>
)
}
/* globals.css */
body {
font-family: var(--font-inter), sans-serif;
}
常见字体配置
中英文混排
import { Inter } from 'next/font/google'
import { Noto_Sans_SC } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
})
const notoSansSC = Noto_Sans_SC({
subsets: ['chinese'],
variable: '--font-noto-sans-sc',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body className={`${inter.variable} ${notoSansSC.variable}`}>
{children}
</body>
</html>
)
}
代码字体
import { Fira_Code } from 'next/font/google'
const firaCode = Fira_Code({
subsets: ['latin'],
variable: '--font-fira-code',
})
export default function CodeBlock({ code }) {
return (
<pre className={firaCode.variable}>
<code>{code}</code>
</pre>
)
}
字体性能优化
预加载关键字体
const inter = Inter({
subsets: ['latin'],
preload: true, // 默认 true
})
限制字重
只加载需要的字重能大幅减少字体文件大小:
// 好:只加载需要的字重
const inter = Inter({
subsets: ['latin'],
weight: ['400', '600', '700'],
})
子集优化
只加载需要的字符集:
// 好:只加载简体中文字符
const notoSansSC = Noto_Sans_SC({
subsets: ['chinese-simplified'],
})
实用建议
这里分享几个在字体优化时特别有用的技巧。
使用 next/font
实际开发中,我发现使用 next/font 比传统方式要好很多:
// 推荐这样做 - 使用 next/font
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
// 传统方式虽然也可以,但功能不如 next/font
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet">
限制字体数量
这里有个小建议:使用过多字体会影响性能,建议整个项目只使用 2-3 个字体。
选择合适的显示策略
这个技巧在实际项目中特别有用——根据使用场景选择合适的显示策略:
- 正文文本建议使用 swap,避免文字不可见
- Logo/标题可以使用 block,保持设计一致性
总结
本节我们学习了 Next.js 的字体优化功能,包括 Google Fonts、本地字体、字体显示策略等。使用 next/font 能自动优化字体加载,消除布局偏移,提升用户体验。
如果你对本节内容有任何疑问,欢迎在评论区提出来,我们一起学习讨论。