早就想写篇关于 server components 的文章了,年底终于有时间了
不可能三角:这是一个关于体验(user experience)、可维护性(maintenance)、性能(performance)抉择的故事
- server / 返回前端 build 的 html,加载 client entry.js
- client
userServerResponse
发送/react
接口,获取 server 吐出的 server components,并用@
开头特殊的 type 标记了 chunk
- client 通过
webpack 运行时插件
拉取 chunks,并更新视图
-
server 中调用的 client 组件,只在吐 server components 时使用,server 并没有实际感知这个文件。最终执行还是在 client 中,所以能正常使用 client 的上下文。另外 server 组件会被层层解析出来
-
server 使用到的 client 组件,由 client build 时 react webpack 插件抽的 chunk,默认处理 xxx.client.xx 文件
-
client webpack 运行时 api 中,通过判断 server components 返回的 k-v 中的 k 的首字母来判断是哪种类型,如果是 module 则调用 __webpack_require__ 加载
- 其中 M 后面的数字,如
M5
,和 server components 中的以@
后的数字一一对应,如@5
-
client 发送
/react
请求时可以通过 query 参数给 server 或 client 组件传递 props。client 可自行维护 Map 缓存,如果 query 参数相同,则前端直接返回 -
server 缓存优化: 生成 server components 时使用了 createRequest,其自带 react internal cache。request 的实现 跟 react-loadable 差不多
-
client 更小的打包体积:在 tree-shake 基础上,还能将更重的运行时依赖存放于后端
-
赋予组件操作数据的能力:将原本通过接口驱动状态的组件,放于服务端来获取数据
-
可以有前后端共享组件
-
code split 自动化:前端只根据 server component 返回的 id 去加载 chunk
-
状态设置:返回的 server component 比 SSR 返回的静态 html 更加灵活
-
增加了服务端压力
-
concurrent mode 不稳定
-
server 会嵌套 client 组件,调用混乱
-
RSC 无法做 SEO,还是需要配合 SSR
-
client、server、shared 组件使用 hooks、server api 等能力也需要合理区分
期待后续发展,大胆尝试,谨慎上线