Next.js项目中自定义字体加载慢且页面闪烁怎么办?

朱莉🍀 阅读 54

我在Next.js项目里引入了本地字体文件,但页面加载时字体总是延迟渲染,出现文字闪烁的情况。之前用标签在头部引入过Google字体倒没问题,换成本地字体后就卡住了。

尝试过把字体文件放在public目录用绝对路径引用,代码是这样的:


<style>
@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
}
body {
  font-family: 'CustomFont', sans-serif;
  transition: font-family 0s 300ms; /* 模拟加载等待 */
}
</style>

但字体还是会在加载完成时突然切换,Lighthouse评分里的字体显示也显示有阻塞渲染的资源。用预加载标签也没改善,有没有更好的优化方案?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
W″记彤
这个问题在 Next.js 项目中挺常见的,尤其是从远程字体切换到本地字体后。字体加载慢 + 页面文字闪烁(FOIT/FOUT)的问题,一般这样处理:

### 1. 使用 next/font 官方方案(推荐)

Next.js 官方出了个字体加载库,专门优化这个问题,可以有效减少字体导致的布局偏移和闪烁。

假设你把字体文件放在 public/fonts/ 下,可以这样处理:

// 在 pages/_app.js 或组件中
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export default function App({ Component, pageProps }) {
return (
<main className={inter.className}>
<Component {...pageProps} />
</main>
);
}


如果是**本地自定义字体**,可以用 next/font/local

const customFont = require('next/font/local')({
src: '../public/fonts/custom.woff2',
});


然后在组件里加 className={customFont.className}

这个库内部做了:
- 字体预加载
- 自动处理 FOIT/FOUT 优化
- 支持 fallback 字体
- 支持按需加载

### 2. CSS 层面优化字体加载行为

如果你还是用 @font-face 手动引入,建议加上 font-display: swap,防止字体加载时阻塞渲染:

@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap; /* 关键属性 */
}


font-display: swap 的作用是优先用 fallback 字体显示文字,等自定义字体加载完成再切换,视觉上更平滑。

### 3. 预加载字体文件(可选)

如果字体文件比较大,可以加上预加载标签,提升加载优先级:

<link rel="preload" href="/fonts/custom.woff2" as="font" type="font/woff2" crossOrigin="anonymous" />


加在 _document.js 里效果最好。

### 总结

推荐优先用 next/font,尤其是 next/font/local,能自动处理字体加载和页面渲染的节奏问题。手动引入字体时一定要加 font-display: swap,防止字体加载导致页面“空白”或“闪烁”。

如果还有问题,可以看下 Lighthouse 报告中具体哪些字体资源阻塞了渲染,再针对性优化。
点赞 5
2026-02-03 11:00
上官艳鑫
字体加载慢和闪烁的问题确实挺烦人的,特别是在Next.js这种强调性能的框架里。以下是优化方案,顺便提醒一下安全相关的注意事项。

### 1. 使用 next/font 模块
Next.js 13+ 提供了专门的 next/font 模块来处理字体加载问题,它能自动优化字体文件并解决闪烁问题。直接用这个模块加载本地字体:

import localFont from 'next/font/local'

const customFont = localFont({
src: [
{
path: '../public/fonts/custom.woff2',
weight: '400',
style: 'normal',
},
],
variable: '--font-custom',
})

export default function App() {
return (
<main className={${customFont.variable} font-sans}>
<style>
{
:root {
--font-custom: ${customFont.style.fontFamily};
}
}
</style>
Hello World!
</main>
)
}


这样可以避免手动写 CSS,并且 Next.js 会帮你优化字体加载逻辑。

---

### 2. 预加载字体资源
如果你不想用 next/font,可以通过预加载字体文件来减少延迟。在 _document.js_app.js 中添加以下代码:

<link
rel="preload"
href="/fonts/custom.woff2"
as="font"
type="font/woff2"
crossOrigin="anonymous"
/>


注意这里的 crossOrigin="anonymous" 很重要!如果你漏掉了,浏览器可能会因为 CORS 策略而阻止字体加载,导致页面空白或者字体失效。

---

### 3. 设置 font-display 属性
为了让字体加载时页面不会闪烁,可以在 @font-face 中设置 font-display 属性为 swapoptional

@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap; /* 或者 optional */
}


swap 表示先用默认字体显示内容,等自定义字体加载完成后切换;optional 则会让浏览器根据网络情况决定是否使用自定义字体。

---

### 4. 压缩字体文件
确保你的字体文件已经压缩到最小体积,比如使用 woff2 格式(比 woff 小得多)。如果字体文件过大,即使优化了加载方式也会拖慢页面。

---

最后再啰嗦一句:记得检查服务器端对字体文件的 MIME 类型支持,以及正确配置 CORS 头部,不然有些浏览器可能加载不到字体文件。折腾完这些,字体加载和闪烁问题应该就能搞定了。
点赞 13
2026-01-31 00:00