初步认知Next.js中ISR/RSC/Edge Runtime/Streaming等新概念

前言

浅窥 nextjs 到目前 v12 版本的几个重点新概念,我们有:

定义说明
ISR增量静态渲染
Edge Runtime边缘运行时
Streaming SSR流式传输 SSR
React Server Components服务器组件

下面我们对这几个新概念进行一个初步的认知,在阅读前,我们默认读者已经预备了 nextjs 的基本知识。

含义认知

ISR

SSRSSG 这两个是冷饭,我们都耳熟能详,那所谓 ISR 增量再渲染的概念,其实是基于 SSG 场景下的混合版 SSR ,也可以理解成加强版 SSG

两种 SSG

对于 SSG 来说,也要分纯 SSG 和带服务端的 SSG

SSGnext export )就是构建时预渲染 html 导出纯静态文件的做法,在 v 圈 nuxt 2 中已经被广泛应用。

而考虑有无限个页面(如电商商品等)的网站,还想要享受 SSG 该怎么办?所以我们就引入了服务端,通过服务端来响应访问,按需 SSG 生成新的页面并缓存,来做到无限页面的应对。这个概念在 nextjs 中即 gSPgetStaticProps ) > fallback , 在非 fallback: false 的场景下发挥作用。

ISR = SSG + SSR ?

我们基于第二种带服务端的 SSG 进一步考虑,因为 SSG 一旦执行便产生缓存,此时的问题就变成了我想让我的缓存失效,不然每次都是最旧的 SSG 首页数据多尴尬。

这就产生了 增量 的概念,那分支就又出现了,是被动还是主动让缓存失效?

  1. 被动:已有功能,开箱即用,即指 gSP > revalidate

  2. 主动:实验性功能,详见 On-demand Revalidation (Beta) ,通过访问 API Routes 来使指定 path 的页面缓存失效(比如商品信息修改,需要让该商品页的缓存马上失效)。

通过以上考虑,我们也逐渐发现 ISR 类似一个带 SSR 要素的 SSG

和 Vercel 设施关联性

nextjs 在 Self-hosting ISR 中也特别提醒到我们在 k8s 多 pod 的场景下,每个实例都有自己的文件系统来缓存 SSG 的页面,这可能产生某些实例一直未被分配流量,导致 fallback blocking 太久体验较差的问题,所以可能需要共享挂载一个文件系统或分区来解决。

这里就引出了 Vercel 基建的关联意义性:Vercel Incremental Static Regeneration

在 Vercel 内会对 ISR 有更好的全局缓存支持,有兴趣的读者可自行探究,此处不做进一步展开。

综上来看,ISR 的普适性和私有化是可行的,因为在 Vercel 强关联的部分上没有致命要素,只存在性能、体验、成本等方面的浪费。

Edge Runtime

此处描述的边缘运行时是将 nextjs Middleware 运行在更小的 runtime 中的一种行为,从而进行更快的响应,详见:

该文中对比了现在最流行的三种提供者:nodejs、lambda(如 AWS)、edge 的优缺点,Middleware 目前是 Beta 实验性功能,但他的设定让 nextjs 更有全栈的拓展面,比如 Auth 的前置校验,此处我们也不做更多描述,请在 RFC 中了解更多。

React 18 场景的交错

RSCReact Server Components ) 中,我们需要明确指定 edge runtime 来强制 react 18 streaming render,否则会被自动静态优化,这是一个 workaround

Streaming SSR

在这里 streaming render 是基于 react 18 Suspense 来说的,Suspense 下的组件会被 streaming 流式传输渲染,做到更小的体积,更快的响应、渲染速度,更好的体验。

值得一提的是和以往 Suspense 认知的区别。

以前的 Suspense 认知

在以前的 experiment 阶段我们更多的是使用 <Suspense /> + React.lazy() + webpack lazyimport 来做拆包:

import React, { Suspense, lazy } from 'react'

const Component = lazy(() => import('./Component'))

function Page() {
  return (
    <Suspense fallback={<LoadingElement />}>
      <Component />
    <Suspense/>
  )
}

如此一来 webpack 便会配合我们把 lazyimport 的 ./Component.js 产物拆出去按需加载,而 React Suspense 会配合我们在未加载完成的时候 fallback 显示加载状态。

新 Suspense 认知

而在 react 18 中 Suspense 被正式化后,我们的着眼点便是如何利用 Suspense 带来的 streaming render 做应用体验上的优化,在 http 基础中我们已经知晓过 streaming transport 的优点,那结合 react 落地到实际中便是 nextjs 正在赋能的聚焦点,这带来了更快的 Suspense 组件响应速度,以及根据用户交互优先级的选择性水合(比如优先传输正在交互 hover 的组件)。

实践中的认知

回归实践,我们要认识到的是,以下三种 Suspense 方式均会在 streaming 中被打开:

import dynamic from 'next/dynamic'
import { lazy, Suspense } from 'react'

import Content from '../components/content'

// These two ways are identical:
const Profile = dynamic(() => import('./profile'), { suspense: true })
const Footer = lazy(() => import('./footer'))

export default function Home() {
  return (
    <div>
      <Suspense fallback={<Spinner />}>
        {/* A component that uses Suspense */}
        <Content />
      </Suspense>
      <Suspense fallback={<Spinner />}>
        <Profile />
      </Suspense>
      <Suspense fallback={<Spinner />}>
        <Footer />
      </Suspense>
    </div>
  )
}

此处就和 webpack lazyimport 没有那么强的配合了,即使是 sync 同步的,也会被 streaming 。所以在 react 18 SSR 场景中应该尽可能多的使用 Suspense

注:

  1. 以上内容被使用前还要遵循一定的前置条件,以及 nextjs 对 streaming 的支持达到成熟阶段。

  2. 关于 streaming 更多的介绍,你可以在 官方文档 阅读到更多。

RSC(React Server Components)

对于 RSC 来说,虽然至今为止掀起了很久的讨论潮,但往往都局限于 很浅的理论层 ,甚至没有相应 code 的表述。到 nextjs 中实践来说,当前 RSC 实现中存在的限制也十分多,可调用的 api 屈指可数甚至没有,仍然只是 demo 阶段。

RSC 的认知

那么我们对 RSC 的认知是一个:能肩负服务端昂贵计算、利用服务端环境的组件提供者。

  • 服务端计算:这一点没有什么额外新意值得描述,最终归宿是提升性能和体验。

  • 服务端环境:这意味着可以进行 nodejs 的 api 调用,鉴权、先置运行保密逻辑等。

得益于 react 18 的 streaming 传输特性,RSC 在大体积组件的传输上有独特的优势,也就是将某些重型依赖做成 RSC 来流式传输提升性能和体验。

React 团队侧计划在 react 18 的某个 minor 阶段开始推进正式的 RSC ,由于业界讨论十分混杂,本文也在此处不多加展开,我们进一步期待新的 react 蓝图。

关于 nextjs 在 RSC 已有的实践落地 demo,你可以在这里查看:

总结

在本文描述中,除了 ISR 外均为较新的 experiment 功能,我们进行了 “认知上的浅尝辄止” 。

继 react hooks 鼻祖跳槽 vercel 后,逐渐出现了 vercel nextjs 做什么,react 就配合出什么的趋势,未来 nextjs 的一切也将成为影响 react 发展的重要一环。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值