Next.js 的三种渲染方式

1,389 阅读3分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

前言

Next.js 是什么

NextJS 是一个用于生产环境的 React 框架,它可以提供生产环境所需的所有功能,开发体验极佳。

提供的功能包括静态及服务器端融合渲染、 支持 TypeScript、智能化打包、 路由预取等,无需任何配置。

为什么要学习 Next.js

对于使用 AJAX 去请求数据的网站来说,相对于写死数据的静态网站,在搜索引擎的优化上是比较差的,而且页面的打开、渲染速度,也比不上普通静态页面。而服务端渲染(SSR),就能够帮助我们,生成一个渲染速度快的、搜索引擎优化良好的、带有数据的静态网站。

而 Next 也是支持了三种设计模式:BSR、SSG、SSR,供我们选择,接下来来聊一下这三种设计模式究竟是什么?

正文

什么是 BSR

BSR 也就是客户端渲染(browser side render),这也是前端最普遍的一种请求、渲染方式,也就是前端通过 AJAX 去异步的请求数据。 最常用的就是 axios

//在 React 中使用
useEffect(() => {
    axios.get('/xxx').then(response => ...).catch(err => ...)
}, [])

但如果请求时间过长,那么这就会导致一直出现白屏的情况,这对于用户体验来说,还是比较差劲的。

什么是 SSG

对于那些,与用户信息无关,每个用户看到的都是同样数据的页面,比如博客的文章内容。那就可以在服务端把这部分的数据渲染到 html 上,返回给前端一个静态页面。这样,每个用户在打开这个页面时,都不再需要请求数据。

Nextjs 给我们提供了一个叫 getStaticProps 的方法:

const getData = async () => {
    // 获取数据
}

我们只需要在前端代码下,添加这个方法,然后通过 props 去获取数据即可

import React from 'react'

const App = (props) => {
    const {data} = props
    return (
        <div>{data}</div>
    )
}

export const getStaticProps = async () => {
  const posts = await getData();
  return {
    props: {
      data: JSON.parse(JSON.stringify(data))
    }
  };
};

这个过程就是动态内容静态化

什么是 SSR

SSG 获取的是与用户信息无关的数据页面,那么服务端渲染 SSR(server side render) 就是用于渲染带有用户信息的数据页面,例如个人信息页面,需要客户端传自己的参数给服务端才能渲染的页面。

那么为什么这个过程不能去做动态内容静态化处理呢?因为用户信息肯定不止几个,那么用户如果有几亿个,就需要提前渲染几亿个页面,等用户请求时,再去遍历这些页面吗?这无疑是不可能的。

那么这时候,就需要使用 SSR 来帮助解决这个问题。 同样的,在前端代码下使用 getServerSideProps 方法

import React from 'react'
import { UAParser } from 'ua-parser-js';

const App = (props) => {
    const {browser} = props
    return (
        <div>你使用的的浏览器是:{browser}</div>
    )
}

export const getServerSideProps = async (context) => {
  const ua = context.req.headers['user-agent'];
  const result = new UAParser(ua).getResult();
  return {
    props: {
      browser: result.ua
    }
  };
};

而这一过程,就叫 用户相关动态内容静态化

但是,要注意的是,有些只能在客户端获取的数据,例如当前浏览器窗口大小这种数据,是无法获取到的,这种情况还是需要使用 BSR 也就是 AJAX 来提交、请求数据。

如何选择使用哪种渲染方式呢?

image.png

有动态内容吗? 没有什么都不用做,自动渲染为 HTML

动态内容跟客户端相关吗? 相关就只能用客户端渲染(BSR)

动态内容跟请求/用户相关吗? 相关就只能使用服务端渲染(SSR)或者 BSR

其他情况可以用 SSG 或 SSR 或 BSR