Next.js 中的 SSG 与 SSR

3,103 阅读7分钟

简介

Next.js是最重要和最广泛使用的React框架之一。今天,它已经成为构建令人惊叹的网络应用的综合框架。

在使用Next.js时,可以列出许多优势。性能、SEO、丰富的开发者体验、TypeScript支持、智能捆绑和路由预取只是几个例子。

除了Next.js提供的所有惊人的功能外,有一个特别的功能是非常强大和惊人的:能够使用不同的预渲染技术。

我们可以在同一个Next.js应用程序中使用服务器端渲染(SSR)和静态网站生成(SSG)。我们还可以让我们的服务器端渲染的应用程序,里面仍然有一些生成的页面。

在这篇文章中,我们将进一步了解这两种预渲染技术的工作原理以及如何使用它们。我们还将了解更多关于这两种技术的具体使用情况。

SSR(服务器端渲染

现代JavaScript框架让我们的开发者的生活变得更加轻松。我们可以使用许多不同的渲染技术来创建强大、丰富的网络应用。

你可能听说过单页应用。单页应用是指在客户端渲染的应用,即使数据可能是从服务器上获取的。

服务器端渲染(SSR)则与此完全相反。SSR描述的是在服务器上预渲染页面的过程,然后在每个用户请求时生成。

当预渲染的页面到达浏览器时,JavaScript代码被运行以使页面具有交互性。这整个过程使加载速度更快。它还使依赖搜索引擎优化的应用程序使用服务器端渲染变得更加容易和可取。

Next.js开箱即做这项工作。默认情况下,它将尝试检测你的应用程序正在使用哪种预渲染技术并获取你的数据。

几年前,在JavaScript变得如此成熟和强大之前,开发人员通常基于HTTP调用返回HTML文件。在服务器端使用服务器端语言(通常是PHP)处理响应,并返回一个静态HTML文件,这是一种非常普遍的技术。

SSG(静态网站生成

静态生成的网站对于开发者来说并不新鲜。从网络诞生之初,我们就一直在构建它们。构建丰富的网络体验可能很难,但有了Next.js,我们可以轻松做到这一点。

Next.js向我们介绍了一种更好的构建静态生成的网站的方法,它具有更多的动态性能。

SSG描述了构建网站的过程,在构建时进行渲染。其输出是一个HTML文件、JavaScript和CSS等资产以及其他一些静态文件。

当与Next.js一起使用SSG时,页面在编译时就已经预先渲染了。这意味着用户不必在浏览器上等待页面的加载;页面将被简单地渲染。

对于数据的获取,Next.js提供了三个不同的函数。

  • getStaticProps。在构建时,页面将被预渲染。
  • getServerSideProps :页面将在运行时被预渲染。
  • getStaticPaths。这个函数生成了一个将在构建时预渲染的页面的列表

使用SSG的最大缺点是构建时间会变得非常长。当你只有几个静态生成的页面时不会有问题,但随着你的应用程序的增长,构建时间会增加。

最糟糕的情况是,你有数百个静态生成的页面。构建时间会很长,如果你在这些页面上有动态内容,你可能会有太多的构建结果。

我应该使用哪一个?

Next.js让我们非常容易为每个页面挑选正确的预渲染技术。

记住,我们知道Next.js默认做静态网站生成。它只是开箱即用。然而,它将尝试检测你在每个页面上使用的预渲染方法。

在某些情况下,选择正确的函数来获取你的数据肯定会有影响。应该考虑到这一点,因为它可以对用户体验造成巨大影响。

想象一下,我们正在创建一个简单的博客网站。内容将是完全静态生成的,对吗?我们将只有几个页面,内容将从我们的服务器上获取,所以在这种情况下,使用SSG是完全有意义的。

我们可以假设每个博客至少有两个基本页面。

  • posts。这个页面负责获取和显示所有的博客文章
  • post。这个页面负责获取和显示一个特定的博客文章

在我们的posts 页面中,我们可以使用SSG来获取我们所有的博客文章,使用getStaticProps 函数。

export default function Posts({ posts }) {
  return (
    <div>
      <h1>My latest posts</h1>
      {posts.map((post) => (
        <h2>{post.title}</h2>
      ))}
    </div>
  );
}

export async function getStaticProps() {
  return {
    props: { 
      posts: await fetchPosts(),
    }
  };
}

fetchPosts 函数将在构建时被运行。它将获取我们的外部数据并为我们的页面预先渲染内容。

现在,想象一下,我们想在我们简单的博客网站上添加一个小功能。

想象一下,我们是一个非常有名的人,我们的追随者想从我们的商店购买物品。我们想把我们的简单博客网站变成一个电子商务应用,并开始销售衬衫、马克杯和贴纸等物品。

一个电子商务应用程序包含的所有组件都可以使用相同的预渲染技术。我们可以在构建时使用getStaticProps 函数来获取我们的数据。

现在,我们可以为我们的结账环节使用什么?每个电子商务应用程序都必须有一个结账环节,用户将在那里结束他们的购买。在这种情况下,数据可以在构建时从我们的数据库中获取,但它对每个用户来说可能是不同的。

我们可以在SSG之上使用客户端获取来渲染我们的页面。我们可以创建我们的简单组件,而不使用任何函数在构建时获取数据,在我们的组件中,我们可以使用一个数据获取库,如SWR,在客户端获取我们的数据。

import useSWR from "swr";
export default function CheckoutSession() {
  const { data, error } = useSWR("/api/checkout", fetcher)
  if (error) return <div>Something went wrong...</div>
  if (!data) return <div>Loading...</div>
  return <div>Cart: {data.items.length}</div>
}

使用服务器端渲染与getServerSideProps ,在大多数情况下可以完成工作。问题是,你可能会失去SSG给Next.js应用程序带来的一些功能和优势。页面将在每次请求时使用返回的数据进行预渲染。另一个缺点是,你不能用一个 [fetch()]([https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch))方法来调用getServerSideProps 内的 API。

事实上,页面在构建时就已经预渲染了,这提高了性能,使页面感觉更快。

HTML也可以由CDN服务器获取,这也可以提高性能。

SSG的另一个很好的特点是不需要对数据库进行请求。页面在构建时就已经预先渲染好了,所以即使你的数据库发生故障,你仍然能够渲染你的页面。

总结

Next.js已经成为网络社区中最重要的React框架之一。它为开发者带来了许多功能,帮助他们建立更复杂和丰富的网站。

使用Next.js这样的框架,我们可以在我们的应用程序上使用不同的预渲染技术。我们可以使用静态网站生成一些更简单和非动态的东西。我们可以对动态内容和更复杂的页面使用服务器端渲染。有了这些工具,构建丰富的网络应用变得更加容易和有趣。

Next.js中的SSG与SSR》一文首次出现在LogRocket博客上。