3
章节3
优化字体和图像
在上一章中,你学习了如何为 Next.js 应用程序添加样式。让我们继续完善主页,添加一个自定义字体和一张英雄图片。
在本章中...
我们将涵盖以下主题:
如何使用 next/font 添加自定义字体。
如何使用 next/image 添加图片。
Next.js 如何优化字体和图片。
为什么要优化字体?
字体在网站设计中扮演着重要角色,但如果项目中的自定义字体文件需要获取和加载,可能会影响性能。
累计布局偏移(Cumulative Layout Shift) 是 Google 用来评估网站性能和用户体验的指标。对于字体而言,当浏览器最初以回退字体或系统字体渲染文本,然后在自定义字体加载后将其替换时,就会发生布局偏移。这种替换可能会导致文本大小、间距或布局发生变化,从而使其周围的元素也发生偏移。

当您使用 next/font 模块时,Next.js 会自动优化应用程序中的字体。它在构建时下载字体文件,并将其与您的其他静态资源一起托管。这意味着当用户访问您的应用程序时,不会有额外的字体网络请求,从而影响性能。
添加主字体
让我们为您的应用程序添加一个自定义的 Google 字体,看看它是如何工作的。
在你的 /app/ui 文件夹中,创建一个名为 fonts.ts 的新文件。你将使用此文件来保存将在整个应用程序中使用的字体。
从 next/font/google 模块导入 Inter 字体——这将是您的主字体。然后,指定您想要加载的子集。在本例中为 'latin'
import { Inter } from 'next/font/google';
export const inter = Inter({ subsets: ['latin'] });最后,将字体添加到 /app/layout.tsx 中的 <body> 元素。
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>{children}</body>
</html>
);
}通过将 Inter 添加到 <body> 元素,该字体将应用于您的整个应用程序。在这里,您还添加了 Tailwind antialiased 类,它能平滑字体。虽然不是必须使用此类,但它能带来更好的视觉效果。
导航到您的浏览器,打开开发者工具并选择 body 元素。您应该会看到 Inter 和 Inter_Fallback 已应用于样式。
练习:添加辅助字体
您也可以将字体添加到应用程序的特定元素中。
现在轮到你了!在你的 fonts.ts 文件中,导入一个名为 Lusitana 的辅助字体,并将其传递给 /app/page.tsx 文件中的 <p> 元素。除了像之前一样指定子集,你还应该指定不同的字体**粗细**。例如,400(正常)和 700(粗体)。
准备好后,展开下面的代码片段以查看解决方案。
提示
最后,<AcmeLogo /> 组件也使用了 Lusitana 字体。它之前被注释掉了以防止错误,现在你可以取消注释。
// ...
export default function Page() {
return (
<main className="flex min-h-screen flex-col p-6">
<div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
<AcmeLogo />
{/* ... */}
</div>
</main>
);
}太棒了,你已经为你的应用程序添加了两种自定义字体!接下来,让我们为主页添加一张英雄图片。
为什么要优化图片?
Next.js 可以将**静态资源**(如图片)放置在顶层 /public 文件夹下。/public 文件夹中的文件可以在您的应用程序中引用。
对于普通的 HTML,你会像这样添加图片:
<img
src="/hero.png"
alt="Screenshots of the dashboard project showing desktop version"
/>然而,这意味着你必须手动
- 确保图片在不同屏幕尺寸下具有响应性。
- 为不同设备指定图片尺寸。
- 防止图片加载时出现布局偏移。
- 懒加载用户视口外的图片。
图片优化是 Web 开发中的一个重要话题,它本身就可以被认为是一个专业领域。与其手动实现这些优化,不如使用 next/image 组件来自动优化您的图片。
<Image> 组件
<Image> 组件是 HTML <img> 标签的扩展,并提供自动图片优化功能,例如:
- 图片加载时自动防止布局偏移。
- 调整图片大小,避免向视口较小的设备发送大图片。
- 默认情况下延迟加载图片(图片在进入视口时加载)。
- 在浏览器支持的情况下,以现代格式(如 WebP 和 AVIF) 提供图片。
添加桌面英雄图片
让我们使用 <Image> 组件。如果您查看 /public 文件夹,您会看到两张图片:hero-desktop.png 和 hero-mobile.png。这两张图片完全不同,它们将根据用户的设备是桌面还是移动设备显示。
在您的 /app/page.tsx 文件中,从 next/image 导入该组件。然后,在注释下方添加图片:
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';
export default function Page() {
return (
// ...
<div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
{/* Add Hero Images Here */}
<Image
src="/hero-desktop.png"
width={1000}
height={760}
className="hidden md:block"
alt="Screenshots of the dashboard project showing desktop version"
/>
</div>
//...
);
}在这里,您将 width 设置为 1000,height 设置为 760 像素。为图片设置 width 和 height 是一个好习惯,可以避免布局偏移,这些值应与源图片具有**相同的**宽高比。这些值*不是*图片渲染的尺寸,而是用于理解宽高比的实际图片文件大小。
您还会注意到 hidden 类用于在移动屏幕上从 DOM 中移除图片,而 md:block 用于在桌面屏幕上显示图片。
您的主页现在应该看起来像这样

练习:添加移动端英雄图片
现在轮到你了!在你刚添加的图片下方,再添加一个 <Image> 组件,用于 hero-mobile.png。
- 图片宽度应为
560像素,高度应为620像素。 - 它应该在移动屏幕上显示,在桌面屏幕上隐藏——您可以使用开发者工具来检查桌面和移动图片是否正确切换。
准备好后,展开下面的代码片段以查看解决方案。
太棒了!您的主页现在有了自定义字体和英雄图片。
推荐阅读
关于这些主题,还有很多内容需要学习,包括优化远程图片和使用本地字体文件。如果您想深入了解字体和图片,请参阅:
这有帮助吗?

