什么是 ISR(Incremental Static Regeneration)

发布时间 2023-12-09 12:21:10作者: JerryWang_汪子熙

ISR(Incremental Static Regeneration)是一种Web前端开发中的静态网页生成技术。它是Next.js框架引入的一项功能,旨在改进静态站点的性能和用户体验。在了解ISR之前,我们需要先了解几个相关的概念。

静态网页生成(Static Site Generation)

静态网页生成是一种生成静态HTML文件的技术,它将数据与页面内容结合,一次性生成所有页面。这种方法的优势在于提高了网站的加载速度和性能,因为访问者可以直接获取静态HTML而无需等待服务器处理。

服务器端渲染(Server-Side Rendering)

服务器端渲染是在每次请求时动态生成HTML页面的过程。这意味着服务器负责渲染页面的内容,并将最终的HTML发送给客户端。这种方法的好处是可以在每次请求时动态地生成页面,以确保始终提供最新的数据。

预渲染(Pre-rendering)

预渲染是一种在构建时生成页面的技术,它不像静态网页生成那样在每次请求时生成。这样可以减轻服务器的负担,但在某些情况下可能会导致页面内容过时。

ISR 的工作原理

ISR 结合了静态网页生成和服务器端渲染的优点。它的核心思想是在构建时生成静态页面,然后在运行时根据需要进行更新。这意味着你可以预先生成大部分静态页面,然后根据用户的请求,在需要时再重新生成某些页面。

在 Next.js 中,ISR 是通过在页面组件中使用 getStaticProps 函数实现的。这个函数在构建时运行,用于获取页面所需的数据。通过在 getStaticProps 中使用 revalidate 选项,可以指定页面的重新生成时间,即多长时间后页面内容将被更新。如果用户在这段时间内访问该页面,他们将获得旧的静态页面,而同时,Next.js 会在后台异步重新生成新的页面内容,并在下一次请求时提供更新后的页面。

ISR 的优势

  1. 提高性能: ISR 允许大部分页面在构建时生成,从而提高了网站的加载速度。用户可以立即获取静态页面,而不必等待服务器响应。

  2. 实时数据: 与传统的静态网页生成不同,ISR 可以在需要时动态更新页面内容。这意味着你可以在不牺牲性能的情况下获取实时数据。

  3. 降低服务器负担: 由于大部分页面在构建时生成,服务器无需在每次请求时都动态生成页面,从而降低了服务器的负担。

举例说明

假设我们有一个博客网站,每篇博客文章都是一个页面。我们希望实现ISR,以便在用户访问每篇文章时,能够提供最新的内容。

  1. 创建博客文章页面

    // pages/blog/[slug].js
    
    import { useRouter } from 'next/router';
    import { getStaticProps } from 'next';
    
    const BlogPost = ({ postData }) => {
      const router = useRouter();
    
      if (router.isFallback) {
        return <div>Loading...</div>;
      }
    
      return (
        <div>
          <h1>{postData.title}</h1>
          <p>{postData.content}</p>
        </div>
      );
    };
    
    export async function getStaticPaths() {
      // Fetch the list of blog post slugs
      const paths = getBlogPostSlugs();
    
      return {
        paths,
        fallback: true, // Set to true to enable ISR
      };
    }
    
    export async function getStaticProps({ params }) {
      // Fetch necessary data for the blog post using the slug
      const postData = getBlogPostData(params.slug);
    
      return {
        props: {
          postData,
        },
        revalidate: 60, // Regenerate page every 60 seconds (1 minute)
      };
    }
    
    export default BlogPost;
    
  2. 启用 ISR

    在上述代码中,我们通过设置 fallback: true 启用了 ISR。这意味着如果用户访问的页面在构建时不存在(例如,新发布的博客文章),Next.js 会在后台重新生成页面并提供更新后的内容。同时,我们通过 revalidate 选项指定了页面重新生成的时间间隔。

    这样,用户可以立即获取现有的静态页面,并在稍后获取更新的内容,而不必等待重新生成。

总体来说,ISR 是一项强大的技术,能够在静态网页生成和服务器端渲染之间找到平衡,提供高性能和实时数据更新的优势。在构建现代Web应用程序时,特别是对于内容频繁变化的页面,使用ISR可以显著改善用户体验。

SSG 是预先生成网页的过程,这意味着在构建阶段,我们会生成所有可能的页面并保存下来。然后,当用户请求一个页面时,我们只需从存储中获取预生成的页面并将其发送给用户。这种方式的好处是,因为页面已经预生成,所以响应速度非常快。然而,对于内容经常变化的网站来说,SSG 不是一个理想的选择,因为每次内容更新,都需要重新构建整个网站。

SSR 则是在用户请求一个页面时,服务器会生成并返回该页面。这意味着每个请求都会触发一个生成页面的过程。这种方式的好处是,能够处理内容频繁更新的情况。然而,因为每个请求都需要生成页面,所以可能会增加服务器的负担,并且可能导致响应时间变慢。

ISR 试图将 SSG 和 SSR 的优点结合起来。在 ISR 中,页面在构建阶段会被预生成,但是可以设置一个 fallback 参数来处理那些未在构建阶段生成的页面。当用户请求一个未预生成的页面时,Next.js 会在后台生成该页面,并返回一个 “fallback” 页面给用户。一旦页面生成,Next.js 会保存它,以便下次请求时可以立即返回。

另外,ISR 还引入了一个 revalidate 参数。这个参数定义了在多长时间后,页面应该被重新生成。例如,如果 revalidate 设置为 1,那么每隔 1 秒,Next.js 会检查页面是否需要更新。如果需要,Next.js 会在后台重新生成页面,并在下次请求时返回新的页面。

让我们以一个博客网站为例来说明 ISR 的使用。假设我们有一个博客网站,其中包含数千篇博客文章。每篇文章都有自己的页面,而且每天都会有新的文章发布。

如果我们使用传统的 SSG,那么每次新文章发布时,我们都需要重新构建整个网站,这将花费大量的时间和计算资源。如果我们使用 SSR,那么每次用户请求一篇文章时,我们都需要在服务器上生成那个页面,这可能会使服务器的负担加重,并可能导致响应时间变慢。