Next.js项目中自定义字体加载慢且页面闪烁怎么办?
我在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评分里的字体显示也显示有阻塞渲染的资源。用预加载标签也没改善,有没有更好的优化方案?
### 1. 使用
next/font官方方案(推荐)Next.js 官方出了个字体加载库,专门优化这个问题,可以有效减少字体导致的布局偏移和闪烁。
假设你把字体文件放在
public/fonts/下,可以这样处理:如果是**本地自定义字体**,可以用
next/font/local:然后在组件里加
className={customFont.className}。这个库内部做了:
- 字体预加载
- 自动处理 FOIT/FOUT 优化
- 支持 fallback 字体
- 支持按需加载
### 2. CSS 层面优化字体加载行为
如果你还是用
@font-face手动引入,建议加上font-display: swap,防止字体加载时阻塞渲染:font-display: swap的作用是优先用 fallback 字体显示文字,等自定义字体加载完成再切换,视觉上更平滑。### 3. 预加载字体文件(可选)
如果字体文件比较大,可以加上预加载标签,提升加载优先级:
加在
_document.js的里效果最好。### 总结
推荐优先用
next/font,尤其是next/font/local,能自动处理字体加载和页面渲染的节奏问题。手动引入字体时一定要加font-display: swap,防止字体加载导致页面“空白”或“闪烁”。如果还有问题,可以看下 Lighthouse 报告中具体哪些字体资源阻塞了渲染,再针对性优化。
### 1. 使用
next/font模块Next.js 13+ 提供了专门的
next/font模块来处理字体加载问题,它能自动优化字体文件并解决闪烁问题。直接用这个模块加载本地字体:这样可以避免手动写 CSS,并且 Next.js 会帮你优化字体加载逻辑。
---
### 2. 预加载字体资源
如果你不想用
next/font,可以通过预加载字体文件来减少延迟。在_document.js或_app.js中添加以下代码:注意这里的
crossOrigin="anonymous"很重要!如果你漏掉了,浏览器可能会因为 CORS 策略而阻止字体加载,导致页面空白或者字体失效。---
### 3. 设置
font-display属性为了让字体加载时页面不会闪烁,可以在
@font-face中设置font-display属性为swap或optional:swap表示先用默认字体显示内容,等自定义字体加载完成后切换;optional则会让浏览器根据网络情况决定是否使用自定义字体。---
### 4. 压缩字体文件
确保你的字体文件已经压缩到最小体积,比如使用
woff2格式(比woff小得多)。如果字体文件过大,即使优化了加载方式也会拖慢页面。---
最后再啰嗦一句:记得检查服务器端对字体文件的 MIME 类型支持,以及正确配置 CORS 头部,不然有些浏览器可能加载不到字体文件。折腾完这些,字体加载和闪烁问题应该就能搞定了。