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,不会出现白屏。


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
引用链接
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