了解 Next.js 数据获取(CSR、SSR、SSG、ISR)

2025-05-28

了解 Next.js 数据获取(CSR、SSR、SSG、ISR)

当我开始学习 Next.js 时,我被一堆看起来相似的缩写弄得晕头转向,不知道它们是什么,也不知道它们有什么区别。这很容易让人困惑,因为在使用 Create React App 时,我们通常只使用一种策略从 API 中获取数据,那就是使用useEffect

Next.js 有多种数据获取策略。尽管 Next.js 最初以服务器端渲染框架而闻名,但事实证明 Next.js 有 4 种数据获取方法。以下是对每种方法的简要说明,以便您熟悉 CSR、SSR、SSG 和 ISR 这几个缩写。

  • CSR - 客户端渲染,这是通常使用的数据获取类型,它将在客户端的useEffect每个页面请求中从 API 获取数据(页面渲染后,该函数将运行)。
  • SSR - 服务器端渲染,将运行一个特殊函数来从服务器端的每个页面请求的 API 中获取数据(在页面加载之前,该特殊函数将首先运行,产生延迟,然后再为页面提供服务)。
  • SSG——静态站点生成,当该页面构建时将运行一个特殊函数来获取数据。
  • ISR – 增量静态再生,这是一个新事物,简而言之,是 SSG 和 SSR 的组合,它以静态方式提供服务,但在特定时间和特定条件下,页面将重建并再次从 API 中获取数据。

如果您不明白,请不要担心,因为我将进行彻底的解释,只需先熟悉一下单词即可。


我之前提到过,使用特定的数据获取方法时会运行一个特殊函数。请记住这一点,我将向您展示这个特殊函数是什么。

此代码示例将使用 axios 从 API 获取日期时间,然后将其渲染到页面上。查看日期时间非常有用,这样我们才能真正了解 API 的调用时间。

客户端渲染(CSR)

特殊功能:useEffect

演示站点

代码示例

export default function CSRPage() {
  const [dateTime, setDateTime] = React.useState<string>();

  React.useEffect(() => {
    axios
      .get('https://worldtimeapi.org/api/ip')
      .then((res) => {
        setDateTime(res.data.datetime);
      })
      .catch((error) => console.error(error));
  }, []);

  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

演示

企业社会责任

条款:

  • PT → 预览时间,即 API 被点击时显示的时间。可以在中间看到。
  • RT → 实时,每秒更新的真实滴答时间,可以在右下角看到

视频说明:

  1. 页面于实时 (RT) 15:46:03 重新加载,然后显示“正在加载”指示
  2. 大约 1 秒后,预览时间显示 15:46:04(太平洋时间)

强调的关键

  1. useEffect 函数,该函数是页面正在使用客户端渲染的关键指标。
  2. LOADING 指示,因为数据获取是在页面渲染完成后进行的,数据并不是立即获取的,因此显示为加载状态。
  3. 每次页面请求时都会获取数据,这就是每次重新加载显示的时间不同的原因。

0-企业社会责任插图


服务器端渲染(SSR)

特殊功能:getServerSideProps

演示站点

代码示例

export default function SSRPage({ dateTime }: SSRPageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getServerSideProps: GetServerSideProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
  };
};
Enter fullscreen mode Exit fullscreen mode

演示

苏维埃社会主义共和国

视频说明:

  1. 在 16:32:38(RT)点击链接,稍停顿 2 秒,然后页面加载显示 16:02:40(PT)

强调的关键

  1. getServerSideProps 函数,该函数是页面是否使用服务器端渲染的关键指标。
  2. 渲染前延迟,且无加载指示,数据在页面渲染前获取,因此此时API 被调用会有轻微延迟,然后页面将显示无加载指示
  3. 每次页面请求时都会获取数据,这就是每次重新加载显示的时间不同的原因。

1-ssr-插图


CSR 与 SSR

这是 CSR 与 SSR 之间的区别,请留意延迟加载指标。

CSR 与 SSR

视频说明:

  1. 单击 CSR 时,立即会出现一个 LOADING 文本,显示一秒钟,然后预览时间加载。
  2. 点击 SSR 时,出现轻微延迟,然后页面加载。

强调的关键

  1. 页面加载后,CSR 访问 API。
  2. SSR 在页面加载之前就访问了 API。

2-csr 与 ssr

简短的补充

我可能会另写一篇文章来分析每种方法的优缺点,但使用CSR时SEO 效果并不好,因为数据只会在页面渲染后才获取。当我们创建带有门控身份验证的页面时,这很有用也很方便,因为像仪表盘、编辑个人资料页面等页面实际上不需要 SEO。

但是,对于服务器端渲染 (SSR) 来说,虽然会造成延迟,但已获取的数据会被注入,从而有助于 SEO。这对于需要吸引流量的帖子或帖子(例如 Reddit 等)非常有用。


静态站点生成 (SSG)

特殊功能:getStaticProps

演示站点

代码示例

export default function SSGPage({ dateTime }: SSGPageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
  };
};
Enter fullscreen mode Exit fullscreen mode

演示

萨格

视频说明:

  1. 预览时间为 13:39:36(太平洋时间)。但实际时间为 16:16:59(实时时间),比实际时间晚了大约 3 小时。
  2. 重新加载并返回主页没有任何改变。

强调的关键

  1. getStaticProps 函数,该函数是页面使用静态站点生成的关键指标。
  2. 运行时获取 yarn build,API在应用程序构建时才会被调用。这就是为什么当前时间为 13:39,而实际时间为 16:17。
  3. 由于没有进一步的获取,数据不会改变,这就是为什么每次重新加载显示的时间都相同。

3-SSG插图


增量静态再生

特殊功能:getStaticProps+revalidate

演示站点

代码示例

export default function ISR20Page({ dateTime }: ISR20PageProps) {
    return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
    revalidate: 20,
  };
};
Enter fullscreen mode Exit fullscreen mode

演示

情报、监视与侦察

免责声明:重新验证时间设置为 20 秒。

视频说明:

  1. 最初是 16:40:12(PT),重新加载时的实际时间是 16:40:25(RT) 和 16:40:29(RT)。在这两次重新加载中,预览时间 (PT) 没有变化。
  2. 然后,在 16:40:32(RT)(初始加载后 20 秒)时,会重新加载两次,第一次分别在 16:40:36(RT) 和 16:40:40(RT)。第二次加载后,预览时间更改为 16:40:37(PT)

强调的关键

现在,这可能会让您感到困惑,但这是我希望您看一下的关键。

  1. 当 20 秒的冷却时间跨度为 16:40:12(RT) - 16:40:32(RT) 时,重新加载不会触发更改。这是因为页面处于冷却状态,正如我们在revalidate按键上设置的一样。
  2. 20 秒冷却时间 - 16:40:32(RT)后,我们进行了 2 次重新加载。
    1. 首次重新加载时间为 16:40:36(RT),我们知道它不再处于冷却状态。冷却状态关闭后的首次访问触发页面重建。页面重建的意思是,只有特定页面会被重建,而不是整个应用程序。Fetch API 将在后台运行,但预览时间不会有任何变化。
    2. 第二次完全刷新时间为 16:40:40(实时时间),预览时间更改为 16:40:37(太平洋时间)。恰好是页面重建后一秒(这意味着重建大约需要 1 秒)。第二次刷新将服务于上次刷新后重建的页面。

4-ISR冷却时间

5-冷却-关闭-ISR

重新访问页面 vs 完全重新加载

isr-重新访问-重新加载

条款:

  1. 重新访问页面 → 使用下一个/链接导航(返回主页,然后再次返回该页面)
  2. 完全重新加载 → 在网站上重新加载(command+r)

视频说明:

  1. 第一次在 18:38:45(RT) 重新访问页面,会触发重建,但第二次重新访问后,预览时间没有变化
  2. 完全重新加载后预览时间将更改为 18:38:45(太平洋时间)

笔记:

  1. 第一次重新加载不必是完全重新加载,我们可以返回主页,然后再次回到该页面(重新访问),只要我们不处于冷却状态,它就会触发重建。
  2. 但是,第二次重新加载必须是完全重新加载。返回主页,然后再次返回该页面不会改变新的预览时间。

现在,我们假设只有一个人访问网站。但是,每次访问都会重新加载,同时仍然遵循冷却状态。

那么它每 20 秒就会重建一次吗?

不。

当冷却时间关闭时,如果没有人访问该页面,那么该页面将不会重建,即使过了 20 多秒也是如此。

但是,当冷却状态为 关闭时,第一个访问的用户触发重建。该用户将看不到更改。但是,这些更改将在下一次完全重新加载时生效。

6-冷却时间图示

结论

就这样吧,朋友们!

如果你已经理解了这些内容,我建议你阅读更多关于如何在它们之间进行选择的文章。我提供了4个指标供你参考,并提供了一些示例!


最初发布在我的个人网站上,在我的网站上可以找到更多博客文章代码片段库,以便于访问🚀

文章来源:https://dev.to/theodorusclarence/understanding-next-js-data-fetching-csr-ssr-ssg-isr-1nff
PREV
如何提升你的开发体验
NEXT
回到基础:我们应该使用 Rem、Em 还是 Pixel?