Next.js For SSR

next.js 与 SSR

术语:

  • 服务器端渲染(SSR):响应每个请求,在服务器上渲染应用程序,然后将水合的HTML和Javascript发送回客户端。

  • 静态渲染(SR):在构建时(例如,当您运行npm run build命令时)渲染应用。通常涉及为每个URL生成一个静态HTML页面。这是NextJS的默认方法。

  • 客户端渲染(CSR):在运行时在浏览器中的客户端上渲染应用程序。

利弊:
即使Next的建议是使用静态渲染,每种方法都有其优点和缺点。

  • 服务器端渲染(SSR):
    优点:

    • 可以动态处理动态路线
    • 渲染页面将始终是最新的

    缺点:

    • 如果要进行繁重的处理可能会很慢,因为客户端在发出请求后必须等待每个页面
    • CDN无法缓存
  • 静态渲染(SR):
    优点:

    • 始终非常快速和高效

    缺点:

    • 如果您不知道所有URL早于(构建)时间,则无法处理动态路由
  • 客户端渲染(CSR):
    缺点:

    • 随着应用程序的增长迅速降低速度,通常应避免使用

NextJS中的SSR,SR和CSR:

getStaticProps —在构建时获取数据
getStaticPaths —在构建时预渲染动态路由
getServerSideProps —在每个请求上获取数据
swr-在运行时从客户端获取数据

基本上,Next.JS将在构建时呈现尽可能多的HTML数据(getStaticProps),然后如果以后需要数据,它将运行getServerSideProps。如果需要在客户端上获取数据,使用swr。

getStaticProps

Next.JS在构建时预先渲染每个页面,并使用 getStaticProps 返回的道具将数据与页面混合。

1
2
const App = ({ data }) => <p>{data}</p>export const getStaticProps = async () => 
({ props: { data: "Some Data" } })

TypeScript Implementation

1
2
3
4
import { GetStaticProps } from 'next'

export const getStaticProps: GetStaticProps = async () =>
({ props: { data: "Some Data" } })

关于getStaticProps的一些重要注意事项:

1.由于它在构建时执行,因此它不会从运行时发出的任何请求接收数据。 其中包括查询参数,HTTP标头等
2.它“仅”运行在“服务器”上,这意味着您可以在此处编写服务器代码,而不会下载到该代码或在“客户端”上运行,例如 API调用,数据库调用,请求等
3.由于它仅在服务器上运行,因此您无需进行本地API调用(例如/ pages / api)。 只需直接在getStaticProps内部编写服务器代码即可。

getStaticPaths

因此,getStaticPaths允许您列出以后希望****需要的动态路由列表,然后在构建时将其渲染(例如,当您运行npm run时) 在您的终端窗口中构建)。 您可以通过返回带有`paths’键(必需)的对象来定义它们。

这就引出了一个问题:“如果** User **请求您未在getStaticPaths中定义的页面会发生什么?”。 返回的对象还具有一个称为“ fallback”的键(必需),该键指示此行为。

如果将“ fallback”关键字设置为“ false”,则所有未定义的路由“ 404”都会退出。

如果将fallback键设置为true,则当User请求未定义页面时,NextJS会抛出在同一文件中定义的fallback HTML,则在后台进行下一步,并使用用户输入的URL完全生成了所请求的页面,然后将其交换为后备HTML。详情参考 docs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { useRouter } from 'next/router'

const Post = ({ post }) => {
const router = useRouter()

if (router.isFallback) {
return <div>Loading...</div>
}

return (
<div>{...post}</div>
)
}

export async function getStaticPaths() {
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
fallback: true,
}
}

export async function getStaticProps({ params }) {
// if url was /posts/3, params.id will be 3
const res = await fetch(`https://.../${params.id}`)
const post = await res.json()

return { props: { post } }
}

export default Post

TypeScript Implementation

1
2
3
import { GetStaticPaths } from 'next'

export const getStaticPaths: GetStaticPaths = async () => {}

getServerSideProps

NextJS将在每次请求时使用getServerSideProps函数呈现页面**,并将使用该函数返回的数据填充组件props。

根据文档,如果您在构建时无法访问页面所需的数据,则仅应使用getServerSideProps。 即请求中包含一些您需要的信息,以提取所需的数据或呈现页面。

注意,getServerSideProps仅在** Server 上运行,并且永远不会下载到 Client 或在 Client **中运行。

1
2
3
4
const Page = ({ data }) => <div>{data}</div>;export const getServerSideProps = async() => {
const res = await fetch(`https://.../data`);
const data = await res.json(); return { props: { data } };
}export default Page;

TypeScript Implementation

1
2
3
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async () => {}

The SWR Hook

Next.JS通常对客户端渲染不满意,但这并不意味着您无法在运行时从客户端获取数据。

Next的聪明人创建了一个名为[SWR](https://swr.vercel.app/)的钩子,该钩子表示**Stale While Revalidate** —反过来又是HTTP缓存失效策略的名称。

我们将在另一篇文章中深入探讨SWR,但与此同时,这里有一个简短的代码片段来演示其用法。

1
2
3
4
5
6
7
8
9
10
import useSWR from 'swr'

const Article = () => {
const { data, error } = useSWR('/api/prices', fetch)

if (error) return <div>There was an error!</div>
if (!data) return <div>Still loading...</div>

return <div>Prices: {data}</div>
}

Conclusion

主要的收获是:尽可能使用静态渲染。 如果您需要信息来渲染仅在用户发出请求时才可用的页面,请使用“服务器端渲染”。 如果您需要实时更新客户端,强烈建议使用SWR。

  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020 Ruoyu Wang
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信