- 客户端渲染(BSR)
- 静态页面生成(SSG)
- 服务端渲染(SSR)
一、 客户端渲染(BSR)
只在浏览器上执行的渲染,数据完全由前端渲染。
静态内容 +动态内容(AJAX 获取)
缺点
- 白屏
在AJAX得到相应之前,页面中只有白色或Loading。 - SEO不友好
搜索引擎访问页面,看不到页面内容数据。因为搜索引擎默认不会执行 JS,只能看到 HTML。
二、 静态页面生成(SSG)
背景
其实每个人看到的文章列表都是一样的,那么为什么还需要在每个人的浏览器上渲染一次,为什么不在后端渲染好,然后发给每个人,N 次客户端渲染变成了 1 次静态页面生成。这个过程叫做 动态内容静态化
显然,后端最好不要通过 AJAX 来获取页面内容数据。
使用 getStaticProps
- 声明位置:每个 page 不是默认导出一个函数么?把
getStaticProps声明在这个函数旁边即可。 - 别忘了加 export
- return props
写法
export const getStaticProps = async () => {
const posts = await getPosts()
return {
props : {
posts: JSON.parse(JSON.stringify(posts))
}
}
}
使用 props
const PostsIndex: NextPage<{post: Post[]}> = (props) => {
// ...
}
静态化的时机
- 在开发环境,每次请求都会运行一次 getStaticProps,这是为了方便你修改代码重新运行。
- 在生产环境,getStaticProps 只在 build 时运行一次,这样可以提供一份 HTML 给所有用户下载
生产环境
- 解读
- λ (Server) SSR 不能自动创建 HTML
- ○ (Static) 自动创建 HTML(发现你没用到 props)
- ● (SSG) 自动创建 HTMLJS JSON (发现你用到了 props
- 三种文件类型
- posts.html含有静态内容,用于用户直接访问
- posts.js 也含有静态内容,用于快速导航 (与 HTML 对应)
- posts.json 含有数据,跟 posts.js结合得到界面
小结
- 动态内容静态化
- 如果动态内容与用户无关,那么可以提前静态化
- 通过 getStaticProps 可以获取数据
- 静态内容 + 数据(本地获取) 就得到了完整页面
- 代替了之前的静态内容 +动态内容(AJAX 获取)
- 时机
- 静态化是在 yarn build 的时候实现的
- 优点
- 生产环境中直接给出完整页面
- 首屏不会白屏
- 搜索引擎能看到页面内容(方便SEO)
三、服务端渲染(SSR)
如果页面跟用户相关呢?
较难提前静态化的情况
需要在用户请求时,获取用户信息,然后通过用户信息去数据库拿数据
有时候这些数据更新极快,无法提前静态化
比如微博首页的信息流
使用 getServerSideProps
- 运行时机
无论是开发环境还是生产环境,都是在请求到来之后运行getServerSideProps - 参数
context,类型为NextPageContextcontext.req / context.res可以获取请求和响应- 一般只需要用到
context.req
写法
const index: NextPage<Props> = (props) =>{
const { browser } = props
return (
<div> 你的浏览器是 {browser.name} </div>
)
}
export default index
export const getServerSideProps: GetServerSideProps = async (context) => {
const us = context.req.header('use-agent')
const result = new UAParser(ua).getResult()
return {
props:{
browser: result.browser
}
}
}
展示了当前用户的浏览器,这些信息不可能在请求之前知道
思考: 如果我要在页面上展示当前窗口大小,可以吗?
答案: 不可以,只能用客户端渲染做到
四、三种渲染如何选择
- 静态内容
直接输出 HTML,没有术语 - 动态内容
术语: 客户端渲染,通过 AJAX 请求,渲染成 HTML - 动态内容静态化
术语: SSG,通过getStaticProps获取用户无关内容 - 用户相关动态内容静态化
术语: SSR,通过getServerSideProps获取请求
缺点:无法获取客户端信息,如浏览器窗口大小
流程图
- 有动态内容吗? 没有什么都不用做,自动渲染为 HTML
- 动态内容跟客户端相关吗? 相关就只能用客户端渲染 (BSR)
- 动态内容跟请求/用户相关吗? 相关就只能用服务端渲染(SSR) 或 BSR
- 其他情况可以用 SSG 或 SSR 或 BSR