Next.js 中的 3 种渲染方式:SSR、SSG 以及 CSR

Next.js 中支持 3 种渲染方式:服务端渲染(Server-Side Rendering,简称 SSR)、静态站点渲染(Static Site Generation,简称 SSG)和客户端渲染(Client-Side Rendering,简称 CSR)。

预渲染

服务端渲染和静态站点渲染都属于“预渲染(Pre-Rendering)”。预渲染就是指在服务端完成外部数据获取以及 React 组件到 HTML 的代码转换,然后将结果网页发送到客户端。

Next.js 中的每张页面默认都会启用预渲染,也就是说网页会在发送到客户端前在服务端生成。

CSR

客户端渲染是指浏览器从服务器接收一个“空 HTML 壳子”,配合用于 hydration 的 JavaScript 代码,完成应用的初始渲染。

我们可以通过 React 的 useEffect() 或数据获取 Hook(比如 useSWR[1])这种客户端渲染方式来为应用程序中的组件提供数据。我分别举例子:

一、使用 useEffect():

import { useState, useEffect } from 'react'
 
function Profile({
  const [data, setData] = useState(null)
  const [isLoading, setLoading] = useState(false)
 
  useEffect(() => {
    setLoading(true)
    fetch('/api/profile-data')
      .then((res) => res.json())
      .then((data) => {
        setData(data)
        setLoading(false)
      })
  }, [])
 
  if (isLoading) return <p>Loading...</p>
  if (!data) return <p>No profile data</p>
 
  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.bio}</p>
    </div>

  )
}

useEffect 会在客户端 React 组件 DOM 挂载后触发,经常用来获取外部系统的数据。

二、使用 useSWR:

import useSWR from 'swr'
 
const fetcher = (...args) => fetch(...args).then((res) => res.json())
 
function Profile({
  const { data, error } = useSWR('/api/profile-data', fetcher)
 
  if (error) return <div>Failed to load</div>
  if (!data) return <div>Loading...</div>
 
  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.bio}</p>
    </div>

  )
}

SWR 是由 Next.js[2] 团队打造。仅需一行代码,你就可以简化项目中数据请求的逻辑,还能体验到数据缓存、请求重试、请求去重等这类实用功能。

预渲染 vs CSR

纯客户端应用在渲染时,会出现短暂白屏。预渲染应用则会立即展示构建好的首屏 HTML,不会出现白屏。

Next.js 中的 3 种渲染方式:SSR、SSG 以及 CSR
客户端渲染初始白屏问题
Next.js 中的 3 种渲染方式:SSR、SSG 以及 CSR
渲染会先生成首屏 UI,后续再激活

SSR

服务器端渲染发生在客户端每次请求后端服务时,页面 HTML 是在这个时候在服务端生成,在返回客户端。

对客户端而言,这些在服务端生成的 HTML 可以用来快速显示不具备交互能力的首屏页面。于此同时,React 会使用一起返回的 JSON 数据和 JavaScript 代码激活页面(即令页面变得可交互。例如:将事件处理程序添加给按钮),这个过程被称为「hydration」

在 Next.js 中,你可以通过在页面中以命名导出 getServerSideProps 函数的方式启用服务器端渲染。「Next.js 将会在每次客户端请求时调用 getServerSideProps 函数」,并用函数内部返回的数据预渲染页面。

下面是一个小例子:

import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
 
type Repo = {
  name: string
  stargazers_count: number
}
 
export const getServerSideProps: GetServerSideProps<{
  repo: Repo
}> = async () => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}
 
export default function Page({
  repo,
}: InferGetServerSidePropsType<typeof getServerSideProps>
{
  return repo.stargazers_count
}

SSG

在 Next.js 中,你可以通过在页面中以命名导 getStaticProps 函数的方式启用静态站点渲染。「Next.js 会在构建阶段(即执行 next build 指令时)调用 getStaticProps 函数」,并使用函数内部返回的数据生成静态 HTML。

静态站点渲染生成的静态 HTML 是随应用部署到服务器,因为我们在构建阶段就生成了网页内容,所以就不像服务端渲染那样,只要将静态 HTML 存储在 CDN[3] 上,并在后续的每次请求中重复使用就行了。

下面是一个小例子:

import type { InferGetStaticPropsType, GetStaticProps } from 'next'
 
type Repo = {
  name: string
  stargazers_count: number
}
 
export const getStaticProps: GetStaticProps<{
  repo: Repo
}> = async () => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}
 
export default function Page({
  repo,
}: InferGetStaticPropsType<typeof getStaticProps>
{
  return repo.stargazers_count
}

总结

Next.js 之美就在于你可以根据每个页面的情况选择最合适的渲染方式,无论是静态站点生成、服务器端渲染还是客户端渲染。

参考链接

  • What is Rendering?[4], from nextjs.org
  • Data Fetching[5], from nextjs.org

引用链接

[1]

useSWR: https://swr.vercel.app/

[2]

Next.js: https://nextjs.org/

[3]

CDN: https://nextjs.org/learn/foundations/how-nextjs-works/cdns-and-edge

[4]

What is Rendering?: https://nextjs.org/learn/foundations/how-nextjs-works/rendering

[5]

Data Fetching: https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side


原文始发于微信公众号(写代码的宝哥):Next.js 中的 3 种渲染方式:SSR、SSG 以及 CSR

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/243974.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!