当前位置: 首页 > news >正文

Next.js 字体优化:使用 `next/font` 告别布局偏移和性能瓶颈

Next.js 字体优化:使用 next/font 告别布局偏移和性能瓶颈

作者:码力无边


在上一篇文章中,我们利用 next/image 组件驯服了图片这头性能猛兽。然而,在追求极致用户体验的道路上,还有一个潜藏的“性能刺客”——网页字体 (Web Fonts)

自定义字体,如谷歌字体 (Google Fonts) 或 Adobe Fonts,能够极大地提升网站的设计感和品牌辨识度。但它们的加载方式也常常会引发两个棘手的问题:

  1. 布局偏移 (Cumulative Layout Shift, CLS):浏览器在渲染页面时,如果自定义字体文件尚未下载完成,它会先使用一个后备的系统字体(如 Arial 或 Times New Roman)来显示文本。当自定义字体最终加载完毕后,文本会突然“变脸”,由于两种字体的字形、间距不同,会导致段落宽度、行高发生变化,从而引发整个页面布局的“抖动”或“偏移”。这对用户体验是毁灭性的,也是谷歌 Core Web Vitals 重点关注的负面指标。

  2. 性能瓶颈 (Flash of Unstyled Text, FOUT):在字体加载完成前,用户可能会看到短暂的无样式文本(或在某些配置下是不可见文本),这种闪烁感同样会降低网站的专业度和体验。此外,从外部服务器(如 fonts.googleapis.com)下载字体文件会增加额外的网络请求,拖慢页面渲染速度。

传统的解决方案通常需要复杂的 CSS @font-face 配置、font-display: swap; 属性以及 preload 链接,手动操作既繁琐又容易出错。

为了彻底解决这些问题,Next.js 13 引入了一个全新的、内置的字体优化系统:next/font。这个模块让你能够以一种极其简单且高效的方式使用自定义字体,同时自动为你处理所有底层优化。

next/font 的核心优势

next/font 模块通过一系列智能的自动化操作,从根本上解决了传统字体加载的痛点:

  • 零布局偏移next/font 在构建时计算出自定义字体的尺寸调整指标,并在 CSS 中自动生成 size-adjust 属性。这使得后备字体的尺寸能够被调整到与最终加载的自定义字体几乎完全一致,从而彻底消除字体加载导致的布局偏移。
  • 自托管与性能:当你使用 Google Fonts 时,next/font 不会向 Google 的服务器发送任何请求。相反,它会在构建时自动下载指定的字体文件,并将其与其他静态资源一起托管在你的服务器上。这意味着:
    • 没有额外的网络请求:减少了 DNS 查询和 TCP 连接的开销。
    • 提升隐私:用户的浏览器不会与第三方字体服务商通信。
  • 自动 font-display: swap;:默认情况下,它会应用最佳实践,确保在字体加载期间文本始终可见。
  • 易于使用:提供了简洁的函数式 API,无论是使用 Google Fonts 还是本地字体文件,都异常方便。

实战一:使用 Google Fonts

这是最常见也最简单的用法。next/font/google 模块内置了对所有 Google 字体的支持。

1. 导入字体函数

假设我们想在整个应用中使用 Inter 字体作为主字体,Roboto Mono 作为代码字体。

pages/_app.tsx (或者你的布局文件中)

import { Inter, Roboto_Mono } from 'next/font/google';
import type { AppProps } from 'next/app';
import '../styles/globals.css';// 2. 调用字体函数并进行配置
const inter = Inter({subsets: ['latin'], // 指定需要的字符子集variable: '--font-inter', // 创建一个 CSS 变量display: 'swap',
});const roboto_mono = Roboto_Mono({subsets: ['latin'],variable: '--font-roboto-mono',display: 'swap',
});// 3. 将字体应用到应用中
export default function MyApp({ Component, pageProps }: AppProps) {// 使用模板字符串组合多个字体的 classNamereturn (<main className={`${inter.variable} ${roboto_mono.variable}`}><Component {...pageProps} /></main>);
}

4. 在你的全局 CSS 中使用 CSS 变量

现在,你可以在 styles/globals.css 中使用我们创建的 CSS 变量来定义全局字体。

styles/globals.css

html,
body {/* 默认使用 Inter 字体 */font-family: var(--font-inter); 
}/* 对于 pre 和 code 标签,使用等宽字体 */
pre,
code {font-family: var(--font-roboto-mono);
}

代码解读

  • 我们从 next/font/google 导入了对应的字体函数。
  • subsets: 这是一个必填项,它告诉 Next.js 只下载你需要的语言字符集(如 latin 用于英语,cyrillic 用于俄语等),从而减小字体文件体积。
  • variable: 这是一个非常强大的功能。它不会直接将 className 应用到元素上,而是创建一个 CSS 变量(例如 --font-inter),让你可以在 CSS 中更灵活地使用这个字体。这是推荐的最佳实践。
  • 我们将生成的 variable 类名应用到了顶层的 main 元素上,使其在整个应用中生效。

实战二:使用本地字体文件

如果你的字体文件(如 .ttf, .woff2)是存放在项目本地的,可以使用 next/font/local

文件结构:

my-app/
├── fonts/
│   └── MyCustomFont-Regular.woff2
├── pages/
└── ...

使用 localFont 函数

import localFont from 'next/font/local';
import Link from 'next/link';// 1. 加载本地字体
const myFont = localFont({src: '../fonts/MyCustomFont-Regular.woff2',display: 'swap',
});// 2. 将字体应用到特定组件
//    注意 .className 的用法
export default function MyComponent() {return (<div><h1 className={myFont.className}>这段文字使用了我的自定义本地字体</h1><p>这段文字使用默认字体。</p><Link href="/"><a className={myFont.className}>这个链接也使用了自定义字体</a></Link></div>);
}

代码解读

  • src 属性指向你的本地字体文件路径。
  • 对于单个组件或页面的局部字体应用,直接使用 myFont.className 是最简单的方式。它会返回一个自动生成的类名,你只需将其应用到需要该字体的元素上即可。

总结:为什么你应该立即采用 next/font

next/font 是 Next.js 对前端性能优化理念的又一次完美体现。它将一个复杂、易错、且对用户体验影响巨大的问题,抽象成了一个简单、优雅且几乎零配置的解决方案。

核心优势回顾:

  • 自动优化:自托管、预加载、size-adjust 等所有最佳实践都已内置。
  • 性能提升:消除外部网络请求,减小字体文件体积。
  • 体验改善:彻底告别布局偏移 (CLS) 和字体加载闪烁 (FOUT)。
  • 开发便捷:无论是 Google Fonts 还是本地字体,API 都极其简洁。

在你的 Next.js 项目中,已经没有任何理由再使用传统的 <link> 标签或 @import 方式来引入字体了。next/font 应该是你处理所有字体需求的首选,也是唯一的选择。

我们已经优化了图片和字体,这是构成页面视觉的两大核心元素。在下一篇文章中,我们将把目光投向另一个常见的性能瓶颈——第三方脚本(如分析工具、广告脚本、客服插件等),学习如何使用 next/script 来驯服它们。敬请期待!


文章转载自:

http://xbQ6M43M.thzgd.cn
http://Owf6yeOt.thzgd.cn
http://MIWKhJuj.thzgd.cn
http://9PCyKkCT.thzgd.cn
http://kJjY9vAE.thzgd.cn
http://PYzYwCel.thzgd.cn
http://1XOki6sO.thzgd.cn
http://idXYPJQi.thzgd.cn
http://KkhqLZHS.thzgd.cn
http://xJbfuW2r.thzgd.cn
http://33DRGjnJ.thzgd.cn
http://N1IoijIy.thzgd.cn
http://K75VMcUO.thzgd.cn
http://VgYvovoT.thzgd.cn
http://Z0dBh8Mu.thzgd.cn
http://H5K7H3OZ.thzgd.cn
http://nSRxuqGX.thzgd.cn
http://EFID7rtf.thzgd.cn
http://oumHLXtb.thzgd.cn
http://qS2x4Lb6.thzgd.cn
http://wuG2vwHq.thzgd.cn
http://RyPFVDjd.thzgd.cn
http://wir4X4I4.thzgd.cn
http://4DYI44ts.thzgd.cn
http://NjYfi6uX.thzgd.cn
http://xOgInVu2.thzgd.cn
http://rH9W2Xv7.thzgd.cn
http://FhS9KVp1.thzgd.cn
http://pZcfWKJZ.thzgd.cn
http://23pwuqTV.thzgd.cn
http://www.dtcms.com/a/379752.html

相关文章:

  • 腾讯滑块---Js逆向酷狗音乐登入
  • 机器学习算法概述
  • zzz‘sJavaweb知识点总结
  • 【STL源码剖析】二叉世界的平衡:从BST 到 AVL-tree 和 RB-tree 的插入逻辑
  • Altium Designer使用精通教程 第四章(PCB封装库绘制)
  • 基于多模态与主动学习的车船飞机图像识别系统研究与应用技术方案
  • cesium的3dtiles模型矫正工具
  • Win7环境中离线安装Visual Studio 2017的相关问题
  • 解决 Typora 0.11.18 版本过期问题
  • 基于R语言机器学习方法在生态经济学领域中的实践技术应用;十大原理、熵权法、随机森林、神经网络、因果推断全解析
  • 数据结构:并查集
  • Unity Addressable System 本地服务器功能验证
  • 用简单的日期类巩固C++类与对象基本知识
  • python+springboot+uniapp微信小程序题库系统 在线答题 题目分类 错题本管理 学习记录查询系统
  • DeepSeek v3.1和DeepSeek R1在编程风格方面的区别
  • kafka启动小脚本
  • AI-调查研究-76-具身智能 当机器人走进生活:具身智能对就业与社会结构的深远影响
  • 机器学习-机器学习模型简介
  • sVLMs之:《SmolVLM: Redefining small and efficient multimodal models》的翻译与解读
  • 【GPT入门】第67课 多模态模型实践: 本地部署文生视频模型和图片推理模型
  • 机器学习-探索性数据分析
  • AVL树旋转全解析:四步让失衡二叉树“华丽转身”
  • 一文学会CMakeLists.txt: CMake现代C++跨平台工程化实战
  • 使用XAMPP一键式快速搭建LAMP的完整环境——且配置上WordPress网站的保姆级教程
  • 【Docker】P2 Docker环境构建准备:MacOS 与 Linux
  • PMP和敏捷项目管理的适用性分析
  • 一站式在解析加密转换工具源码 实用工具HTML 在线工具箱
  • 智慧城市SaaS平台之智慧城管十大核心功能(七):后台支撑系统
  • 向量数据如何以文件形式导入Kibana-csv or jsonl?
  • VSCode与Linux环境配置