next.js ISR 学习笔记

707 阅读3分钟

提供静态生成(Static Site Generation 简称SSG)、服务端渲染(Server-Side Rendering 简称SSR)(包括静态增量更新(Incremental Static Regeneration简称ISR))两大种与渲染方式已达到浏览页面时省去客户端获取数据再渲染呈现页面的时间成本。

  • 可以提升用户体验,对SEO更友好。
  • 可以在页面组件内部进行动态网络请求,getStaticProps、getStaticPaths是在构建期间进行网络请求的,如果需要动态请求数据可以在组件内部请求然后csr渲染

next.js使用文件目录协议路由的方式

-project
    -pages
        -list
            [number].tsx

http://localhost:3000/list/123123

SSG:

  • getStaticProps API

  • 用于构建单个静态页面,

  • -页面可以在用户访问前就构建出来且内容不是实时/条件动态变化的

  • -页面可以公开/缓存的非私密页面

  • -页面对首屏加载速度/SEO有要求的

  • 缺点:构建页面会生成一个html文件和对应数据来源的json文件,可以在network上预览这个json,安全性不好

  • DEMO: [number].tsx

    import { GetStaticPaths, GetStaticProps, NextPage } from 'next' export const getStaticProps: GetStaticProps = async (ctx) => { const id = ctx.params!.number // 这个number是文件名[number]中的number 会截取页面地址(http://host/list/30)中的30 try { const result: any = await getData(id) return { props: { result }, } } catch (error) { // return { notFound: true, revalidate: 100 } return { redirect: { destination: '/', permanent: false, }, } } } const HomePage: NextPage = (props: IProps) => { return ... }

notFound: true直接重定向到404页面

redirect:重定向到指定页面

SSR:

export const getStaticPaths: GetStaticPaths = async (ctx) => {
  const paths = 30 // 假如我们有10w页生成前30页
  return { paths }
}

那么这个页面的地址为 http://localhost:3000/list/1  -> 30

ISR:

像这种动态地址的页面我们可以用getStaticProps 来实现静态增量更新(ISR)

假如我们有200w条静态数据可供展示查询 数据每页有20条共10w页

如果单纯的使用SSR&SSG (getStaticPaths返回100000)我们需要在构建时生成10w个页面时间成本过高

这时可以使用ISR

export const getStaticProps: GetStaticProps = async (ctx) => {
  const id = ctx.params!.number // 这个number是文件名[number]中的number 会截取页面地址(http://host/list/30)中的30
  try {
    const result: any = await getData(id)
    return {
      props: {
       result
      },
    }
  } catch (error) {
    // return { notFound: true, revalidate: 100 }
    return {
        redirect: {
          destination: '/',
          permanent: false,
        },
        revalidate:100 // 每100秒重新构建
      }
  }
}
export const getStaticPaths: GetStaticPaths = async (ctx) => {
  const paths = await getPage(30) // 假如我们有10w页生成前30页
  return { paths, fallback: 'blocking' }
}

revalidate:100 用于定时更新页面数据,如下方推荐列表之类的可能会人为改变的动态内容

-间隔100秒后重新构建

-如果值是false则在下次发版前都不会重新构建页面

fallback:降级处理

运行时静态生成需要一些时间(用户请求等着要 HTML),在此过程中有 3 种选择:

  • fallback: false:不降级,命中尚未生成静态页面的路由直接 404

  • fallback: true:降级,命中尚未生成静态页面的路由先返回降级页面(此时props为空,一般显示个 loading),静态生成 HTML 的同时会生成一份 JSON 供降级页面 CSR 使用,完成之后浏览器拿到数据(在客户端填上props),渲染出完整页面

  • fallback: 'blocking':不降级,并且要求用户请求一直等到新页面静态生成结束(实际上就是 SSR,渲染过程是阻塞的,只是完成之后会保留结果 HTML)

这样的话当用户访问一个还没有构建的页面这个用户会等待页面在服务器渲染好后才会看见,这个页面会在服务器保存,下次再被请求会直接返回这个页面,牺牲第一个访问用户的等待时间来触发页面的构建。