最近学习了Next.js 14框架,总结一下预渲染技术和具体代码用法,如果有理解不对的地方还请大佬指正。
注意以下内容只讨论App Router的新方案(getStaticProps已经弃用)。
1.简介
预渲染主要分为2种技术,静态页面渲染(SSG)和服务器端渲染(SSR)
预渲染简单说就在客户端访问网页页面时,由服务器返回完整的html文件,而不是部分数据。
2.静态页面渲染(SSG)
使用场景:页面内容基本不怎么变动,又考虑SEO优化和首次页面加载速度快。
优点:SEO优化,首次页面加载速度快,服务端和客户端压力都小。
缺点:内容更新不及时。
实现:在编译项目的时候就把js动态页面编译成html静态页面,客户端访问时,服务器直接返回完整html文件,有点返璞归真的意味。
主要情况有以下4种情况:
1.以下是一个页面(Page.js)的内容,在一个页面中没有任何动态操作时,会被默认编译成静态页面html。
export default function MyPage(){
return <main>
<h1>我的首页!</h1>
</main>
}
2.以下是一个页面(Page.js)的内容,在页面中上来就执行fetch操作时,会被默认编译成静态页面。在编译时会直接去拉取https://jsonplaceholder.typicode.com/users的信息生成html。
export default async function MyPage(){
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await response.json()
//以下不必关心,主要看上面
return(<>
...此处省略
</>)
}
3.动态路由
在动态路由中,如果希望生成静态页面,可以添加getStaticPaths函数,然后指定id,对应的id的页面就在编译时生成静态页面。
export default async function Post({ params }) {
const id = params.postId
const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)//在服务器端获取数据
const data = await response.json()
//以下不必关心,主要看上面
return (
...此处省略
)
}
export async function getStaticPaths(){
return {
paths: [
{
params:{postId: '1'}
},
{
params:{postId: '2'}
},
{
params:{postId: '3'}
}
],
fallback: false
}
}
其中fallback为false,表示访问除了指定的1,2,3的postId之外的其他页面全报404找不到。
其中fallback为true,表示访问除了指定的1,2,3的postId之外,在客户端第一次访问该页面时,会先返回一个加载过渡页面,服务器会去尝试静态生成html,然后再返回html给客户端。
其中fallback为block,表示访问除了指定的1,2,3的postId之外,在客户端第一次访问该页面时,会卡住等待,服务器会去尝试静态生成html,然后再返回html给客户端。
4.增量静态生成 ISR(Buff叠加)
如果页面的内容是会更新的,纯纯的静态页面就无法满足了,那么可以使用ISR技术。
说人话就是,我虽然是静态页面,但是我只保持给定时间(如5秒钟),超过5秒钟后,如果有客户端来访问,服务器就重新去fetch数据,重新生成一次html再返回给客户端。
export const revalidate = 5 //5s后如果有请求,则重新生成该页面
export default async function MyPage(){
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await response.json()
//以下是data的使用,不必关心,主要看上面
return(<>
...此处省略
</>)
}
如上,只需要把revalidate设定并export出去,就可以使用ISR技术了,是不是很简单。
3.服务端页面渲染(SSR)
使用场景:页面内容经常变动,又考虑SEO优化和首次页面加载速度快。
优点:SEO优化,首次加载速度快,客户端压力小。
缺点:服务端压力变大。
实现:服务端渲染就是客户端每次页面访问时,服务器都会重新fetch拉取数据,并重新生成html,再返回给客户端。
使用方法如下。
export default async function MyPage(){
const response = await fetch('https://jsonplaceholder.typicode.com/users',{ cache: 'no-store'})
const data = await response.json()
//以下不必关心,主要看上面
return(<>
...此处省略
</>)
}
只需要在fetch后面加入{ cache: 'no-store'}就可以开启了,是不是很简单。
4.客户端页面渲染(CSR)
使用场景:用户动态交互很多的页面,也不需要SEO优化。
优点:动态交互,服务器压力小。
缺点:首次加载速度慢,页面内容不是纯html,不利于SEO优化。
实现:这种就是传统的react中使用的方式,客户端利用useEffect去拉取数据,注意开头一定要标明"use client",这种方式不是next.js中新增的方式,但是也可以在next.js中使用。
"use client"//默认next.js为"use server",所有使用CSR时必须添加该标识
import { useState,useEffect } from "react";
//客户端获取数据的方法
export default function MyPage(){
const [data, setData] = useState(null)
useEffect(()=>{
async function fetchMyData() {
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const data = await response.json()
setData(data)
}
fetchMyData()
},[])
//以下不必关心,主要看上面
return (
...此处省略
)
}
总结
在实际开发一个网站时,可能需要将以上几种方案混合在一起,发挥各自的特长,而且这些都可以在Next.js中做到,是不是很强大?哈哈,以上是我的学习总结,希望能帮到你,加油💪🏻