Skip to content

Next.js 图片和字体

在现代 Web 开发中,优化图片和字体对于提升网站性能和用户体验至关重要。Next.js 提供了一系列内置功能,可以帮助你轻松地处理这些静态资源,实现自动优化。

1. 静态文件服务

Next.js 通过 public 目录来提供静态文件服务,例如图片、图标、robots.txt 等。public 目录下的任何文件都可以通过应用的根 URL (/) 来访问。

示例:

  1. 将一张名为 logo.png 的图片放入 public 目录。
  2. 你可以在代码中通过 /logo.png 来引用这张图片。
jsx
function MyLogo() {
  return <img src="/logo.png" alt="My Company Logo" />;
}

注意:不要将 public 目录用于存放编译后的资源或动态生成的文件。它只应用于存放不需要构建处理的静态资源。

2. 图片优化 (next/image)

直接使用 HTML 的 <img> 标签可能会导致性能问题,例如:

  • 加载大尺寸图片:即使在小屏幕设备上,也会加载原始尺寸的图片,浪费带宽。
  • 无懒加载:视口外的图片会立即加载,影响初始页面加载速度。
  • 布局偏移 (Layout Shift):图片加载时可能会导致页面布局突然变化。

为了解决这些问题,Next.js 提供了 <Image> 组件,它是对 <img> 标签的扩展,并提供了自动的图片优化功能。

如何使用 next/image

  1. 导入组件

    jsx
    import Image from 'next/image';
  2. 使用组件

    jsx
    import profilePic from '../public/me.png'; // 导入本地图片
    
    function MyProfile() {
      return (
        <Image
          src={profilePic} // 可以是静态导入的图片或一个 URL 字符串
          alt="Picture of the author"
          width={500} // 必须提供尺寸以避免布局偏移
          height={500}
          // placeholder="blur" // 可选:提供模糊占位图
          // blurDataURL="..." // 可选:自定义模糊占位图
        />
      );
    }

next/image 的核心优势

  • 自动调整尺寸:根据设备屏幕大小提供正确尺寸的图片。
  • 自动懒加载:默认情况下,视口外的图片会延迟加载。
  • 防止布局偏移:通过要求提供 widthheight 属性,可以预留图片空间,防止页面跳动。
  • 自动格式转换:可以自动将图片转换为现代格式(如 WebP),以减小文件大小。

远程图片

如果你需要加载来自外部 CDN 或其他域的图片,你需要在 next.config.js 文件中配置允许的域名,以确保安全。

js
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https'
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
  },
}

3. 字体优化 (next/font)

Web 字体的加载同样会影响性能,可能导致 FOIT (Flash of Invisible Text) 或 FOUT (Flash of Unstyled Text)。Next.js 13 推出了 next/font 模块,用于优化字体加载。

next/font 会在构建时下载字体文件,并将其与其他静态资源一起托管。这意味着:

  • 无外部网络请求:浏览器无需向 Google Fonts 等服务发送额外的网络请求。
  • 隐私友好:不会与第三方服务共享用户信息。
  • 自动 font-display:自动设置 font-display: optional,以获得最佳性能。

如何使用 next/font

使用 Google Fonts

  1. next/font/google 导入字体

    javascript
    import { Inter, Lusitana } from 'next/font/google';
  2. 加载字体

    javascript
    const inter = Inter({ subsets: ['latin'] });
    const lusitana = Lusitana({ subsets: ['latin'], weight: ['400', '700'] });
  3. 在组件中应用字体

    你可以将字体应用于全局或特定元素。

    全局应用 (在 _app.js 中):

    jsx
    // pages/_app.js
    import { Inter } from 'next/font/google';
    
    const inter = Inter({ subsets: ['latin'] });
    
    export default function MyApp({ Component, pageProps }) {
      return (
        <main className={inter.className}>
          <Component {...pageProps} />
        </main>
      );
    }

    局部应用:

    jsx
    const lusitana = Lusitana({ subsets: ['latin'], weight: ['400', '700'] });
    
    function Heading() {
      return <h1 className={lusitana.className}>My Heading</h1>;
    }

使用本地字体

  1. next/font/local 导入

    javascript
    import localFont from 'next/font/local';
  2. 加载本地字体文件

    javascript
    const myFont = localFont({ src: '../styles/my-font.woff2' });
  3. 在组件中应用

    jsx
    function MyComponent() {
      return <p className={myFont.className}>This text uses a local font.</p>;
    }

总结

Next.js 通过 next/imagenext/font 提供了强大的内置优化功能,可以显著提升网站的性能和用户体验。通过使用这些工具,你可以确保图片和字体以最高效的方式加载,同时避免常见的性能陷阱。在下一章中,我们将探讨如何组织和构建可重用的组件与布局。

本站内容仅供学习和研究使用。