初步认知Next.js中ISR/RSC/Edge Runtime/Streaming等新概念
前言
浅窥 nextjs 到目前 v12 版本的几个重点新概念,我们有:
定义 | 说明 |
---|---|
ISR | 增量静态渲染 |
Edge Runtime | 边缘运行时 |
Streaming SSR | 流式传输 SSR |
React Server Components | 服务器组件 |
下面我们对这几个新概念进行一个初步的认知,在阅读前,我们默认读者已经预备了 nextjs 的基本知识。
含义认知
ISR
SSR
、SSG
这两个是冷饭,我们都耳熟能详,那所谓 ISR
增量再渲染的概念,其实是基于 SSG
场景下的混合版 SSR
,也可以理解成加强版 SSG
。
两种 SSG
对于 SSG
来说,也要分纯 SSG
和带服务端的 SSG
。
纯 SSG
( next export
)就是构建时预渲染 html
导出纯静态文件的做法,在 v 圈 nuxt 2 中已经被广泛应用。
而考虑有无限个页面(如电商商品等)的网站,还想要享受 SSG
该怎么办?所以我们就引入了服务端,通过服务端来响应访问,按需 SSG
生成新的页面并缓存,来做到无限页面的应对。这个概念在 nextjs 中即 gSP
( getStaticProps
) > fallback
, 在非 fallback: false
的场景下发挥作用。
ISR = SSG + SSR ?
我们基于第二种带服务端的 SSG
进一步考虑,因为 SSG
一旦执行便产生缓存,此时的问题就变成了我想让我的缓存失效,不然每次都是最旧的 SSG
首页数据多尴尬。
这就产生了 增量 的概念,那分支就又出现了,是被动还是主动让缓存失效?
被动:已有功能,开箱即用,即指
gSP
>revalidate
。主动:实验性功能,详见 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 中的一种行为,从而进行更快的响应,详见:
- RFC: Switchable Next.js Runtime
该文中对比了现在最流行的三种提供者:nodejs、lambda(如 AWS)、edge 的优缺点,Middleware 目前是 Beta 实验性功能,但他的设定让 nextjs 更有全栈的拓展面,比如 Auth 的前置校验,此处我们也不做更多描述,请在 RFC 中了解更多。
React 18 场景的交错
在 RSC
( React 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
。
注:
以上内容被使用前还要遵循一定的前置条件,以及 nextjs 对 streaming 的支持达到成熟阶段。
关于 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,你可以在这里查看:
- vercel/next-react-server-components
总结
在本文描述中,除了 ISR
外均为较新的 experiment 功能,我们进行了 “认知上的浅尝辄止” 。
继 react hooks 鼻祖跳槽 vercel 后,逐渐出现了 vercel nextjs 做什么,react 就配合出什么的趋势,未来 nextjs 的一切也将成为影响 react 发展的重要一环。
初步认知Next.js中ISR/RSC/Edge Runtime/Streaming等新概念相关推荐
- js中复制对象的属性值给新的对象
我们有一个对象,且包含很多属性值和方法,但是我们想把它的内部属性复制给一个新的对象时,我们如何去做呢? 你可能会说直接 a = b就可以了. no no no,这样两个对象其实指针指向的还是一个内存中 ...
- JS中的堆和栈怎么理解?
JS中其实是没有堆和栈的概念的,但是为了方便我们理解代码的执行过程以及执行方式,我们可以设想这么一个概念: JS把简单的数据类型存放到了栈里,在栈里直接开辟一块空间存放值: 那么复杂数据类型呢? JS ...
- new 实例化对象是啥意思_二. 初步认识JS中的类和对象
1 构造函数的定义 在JS中, 没有类(class)的概念, 主要是通过构造函数来模拟的. 语法 function 构造函数名 () {// 函数体} 使用function关键字表示定义一个构造函数 ...
- 关于浏览器运行原理的初步认知
在对浏览器运行原理的认知过程中我们首先需要精细的了解一些"概念" 这些"概念"也许理解起来很容易,但没有精细理解的时候很容易忽视 而在没有精细了解这些" ...
- [JavaScript] 探索JS中的函数秘密
函数长啥样? 把一些要重复使用的内容封装到函数内. function foo(title) {console.log(title) } foo('title') foo('dust') foo('he ...
- eclipsevue代码怎么运行_[Java教程]使用eclipse初步学习vue.js操作
[Java教程]使用eclipse初步学习vue.js操作 0 2017-11-26 19:00:06 一.vue.js的初步认识 https://unpkg.com/vue ">vu ...
- JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解
前 言 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于汇编语言这样的面 ...
- JS基础--函数与BOM、DOM操作、JS中的事件以及内置对象
前 言 絮叨絮叨 这里是JS基础知识集中讲解的第三篇,也是最后一篇,三篇JS的基础,大多是知识的罗列,并没有涉及更难得东西,干货满满!看完这一篇后,相信许多正在像我一样正处于初级阶段的同学, ...
- js中当等于最小值是让代码不执行_从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理...
前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------超长文+多图预警,需要花费不少时间.---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏 ...
最新文章
- 对用批处理写的chm反编译工具小析
- mysql 开启远程
- 微信小程序python自动化测试_微信小程序的自动化测试框架
- python学习-日志(logging的定义、参数、format、示例代码、创建logging对象、设置Handler)
- Hadoop配置文件参数详解
- C语言错误c2063,请教C语言中关于将二维数组复制到一个三维数组的问题
- Spring Framework 源码解析课程大纲
- 声卡loopback有什么用_萌新做音乐那点事 | 外置专业声卡的选择方法与推荐
- java 置位_java安全编码指南之:Mutability可变性详解
- 语音信号处理(赵力)作业答案第8章——语音合成
- android 开门动画,Android之高仿微信“开门动画”(六)
- win10锁屏账户和计算机名,如何隐藏Windows 10锁屏姓名及电子邮件地址
- 设计模式 -- 组合模式(Composite)
- 路由器交换机:静态路由
- xsy1436-括号游戏
- js关闭当前弹出的小窗口并打开新窗口
- strlen()函数
- 深度分析这一年「AI大咖」,最重要的跳槽原因是……
- 转载,python处理excel转换成xml文件
- 业务应用系统的业务操作日志设计
热门文章
- 体育生学编程——html学习
- 【HTML】html基本标签-1(文字,列表,图片标签)
- qla2xxx 0000:04:00.0: scsi(1:0:2): Abort command issued -- 1 1b22e 2002.
- 电脑下载了谷歌浏览器,设置无法默认选用谷歌浏览器
- JAVA、PHP身份证、统一社会信用代码算法解析验证
- 【Linux系统】centos 停止维护有什么影响呢?
- 麒麟子Cocos Creator 3D研究笔记十:【qfw】开源的Extension Pack for Cocos Creator 3D
- node.js使用puppeteer来html生成pdf
- jstat命令查看jvm的GC情况
- 湖北民院OJ 最少美元付款