Next.js 怎么提供静态文件服务?

文章导读
Previous Quiz Next Static Site Generation 是 Next.js 中使用的一种优化技术,通过它可以在用户界面上快速渲染 HTML 页面。在本章中,我们将学习什么是静态站点生成、静态站点生成的优点,以及如何在从外部源获取数据时实现静态站点
📋 目录
  1. A 什么是静态渲染?
  2. B 不获取数据时的静态生成
  3. C 通过获取外部数据进行静态生成
  4. D 动态路由中的静态生成
  5. E 何时使用静态站点生成?
A A

Next.js - 静态站点生成



Previous
Quiz
Next

Static Site Generation 是 Next.js 中使用的一种优化技术,通过它可以在用户界面上快速渲染 HTML 页面。在本章中,我们将学习什么是静态站点生成、静态站点生成的优点,以及如何在从外部源获取数据时实现静态站点生成。

什么是静态渲染?

Static Rendering(或 Static Site Generation)是一种服务器渲染策略,在构建应用程序时生成 HTML 页面。这意味着在生产环境中,当运行 'next build' 时生成 HTML 页面。此 HTML 将在每个请求中被重用。

  • 在 Static Rendering 中,HTML 页面只构建一次,然后由 CDN 缓存并几乎即时地提供给客户端。
  • 这种渲染方式提升了应用程序的性能和用户体验。
  • 默认情况下,所有不涉及从外部源获取数据的 Next.js 组件都遵循静态渲染策略。
  • 静态渲染常用于博客页面、文档页面和营销页面。

不获取数据时的静态生成

如上所述,所有不涉及从外部资源获取数据的组件都将静态生成。请查看下面的示例。

示例

这是一个静态的 'About' 页面,对所有用户都是一样的。因此,该页面将在构建时生成一次,然后作为缓存存储。

export default function About() {
    return (
      <div>
        <h1>About Us</h1>
        <h2>Welcome to the  About page!</h2>
        <h4>This page is same for all users</h4>
      </div>
    );
}

输出

上述代码的输出将是一个简单的 About 部分的 HTML 页面。该页面对所有用户都是一样的。

Static site

通过获取外部数据进行静态生成

如果您想在构建时获取数据来创建静态页面,可以使用 'getStaticProps()' 函数。该函数将在构建时获取数据一次,然后基于它创建一个完整的 HTML 文件。此 HTML 文件将提供给所有用户。请查看下面的示例。

示例

在下面的代码中,我们将在构建时使用 'getStaticProps()' 函数获取 API 数据,然后将其作为 prop 传递给 React 组件。

// app/page.tsx

import React from 'react';

// 从 getStaticProps 函数接收 posts prop
export default function Blog({ posts }) {
  return (
    <div>
      <h1>Blog Posts</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

// 导出 getStaticProps 函数,在构建时获取数据
export async function getStaticProps() {
    // 模拟从 API 获取数据
    const response = await fetch('https://link/to/api');
    const posts = await response.json();
  
    return {
      props: {
        posts, // 这将作为 props 传递给 Blog 组件
      },
    };
}

输出

在这个输出中,我们在静态页面中显示来自 API 的数据。

SSR external data

动态路由中的静态生成

静态生成也可以用于带有动态路由的页面。动态路由表示页面的路由(即 URL)将依赖于外部来源的数据。例如,你可以创建一个名为 pages/product/[id]/page.tsx 的文件,根据产品的 ID 来显示产品。这将允许你在访问 localhost/product/1 时显示 id 为 1 的产品。

示例

为了处理动态路由 URL,Next.js 允许你从动态页面(在本例中为 pages/product/[id]/page.tsx)中导出一个名为 'getStaticPaths' 的 async function。此函数在构建时被调用,并允许你指定要预渲染的路径。

// pages/product/[id]/page.tsx 文件

// 此函数在构建时被调用
export async function getStaticPaths() {
    // 调用外部 API 端点来获取产品 ID
    const res = await fetch('https://link/to/api');
    const products = await res.json();
    
    // 根据产品获取要预渲染的路径
    const paths = products.map((product) => ({
        params: { id: product.id.toString() }, // 确保 id 是字符串
    }));
    
    // 我们只会在构建时预渲染这些路径。
    // { fallback: false } 表示其他路由应返回 404。
    return { paths, fallback: false };
}

// 此函数也在构建时被调用
export async function getStaticProps({ params }) {
    // params 包含产品 `id`。
    // 如果路由是 /product/1,则 params.id 为 1
    const res = await fetch(`https://.../product/${params.id}`);
    const product = await res.json();
    
    // 通过 props 将产品数据传递给页面
    return { props: { product } };
}

// 用于显示产品详情的页面组件
export default function ProductPage({ product }) {
  return (
    <div>
      <h1>Product {product.id}</h1>
      <p>This is the product page for item {product.id}</p>
      <p>Title: {product.title}</p>
    </div>
  );
}

输出

这是动态路由的输出。页面会根据从服务器获取的产品 ID 而变化。

ssr-dynamic-routing

何时使用静态站点生成?

静态站点生成适用于以下类型的页面:

  • 内容很少变化的页面,例如博客或文档。
  • 需要快速加载以提升用户体验和 SEO 的页面。
  • 可以容忍数据略微过时的页面,因为更新需要重新构建站点。