• 首页
  • 归档
    • 时间线
    • 文章分类
    • 文章标签
  • 留言
  • 关于
  • 首页
    归档
    时间线
    文章分类
    文章标签
    留言
    关于
    VenDream’s Blog
    VenDream’s Blog
    智性孤独
  • 首页
  • 归档
    • 时间线
    • 文章分类
    • 文章标签
  • 留言
  • 关于
  • 首页
    归档
    时间线
    文章分类
    文章标签
    留言
    关于
    前端(3)
    音乐(2)
    react(2)
    notion(1)
    windows(1)
    字体(1)
    StableDiffusion(1)
    WebSocket(1)
    SSE(1)
    AI(1)
    RSC(1)
    Avicii(1)
    心情随想(1)音乐分享(2)技术分享(1)生命在于折腾(1)阅读笔记(4)
    © 2021-2025 VenDream.

    Powered by NotionNext 4.7.0

    Why React Server Components Are Breaking Builds to Win Tomorrow 阅读笔记
    Why React Server Components Are Breaking Builds to Win Tomorrow 阅读笔记
    阅读笔记|2024-3-5|最后更新: 2024-3-28
    前端
    react
    RSC
    type
    status
    date
    Mar 5, 2024 08:13 AM
    slug
    summary
    tags
    category
    icon
    password
    原文:https://www.builder.io/blog/why-react-server-components

    总结

    React生态下前端UI呈现技术的演进过程
    notion image
     
    Client-side rendering (CSR)
    传统SPA中使用的技术,页面的所有UI完全交由客户端渲染。
    大概的渲染流程:
    CSR的缺点:
    • SEO不友好,服务端返回的html中一般只包含一个应用的挂载点div
    • 客户端执行js生成UI的过程耗时长,用户需要等待
     
    Server-side Rendering (SSR)
    基于上述CSR中提到的缺点,提出了SSR的技术,即:HTML的完整文档结构完全交由服务端渲染生成并返回给客户端。
    大概的渲染流程:
    SSR同时解决了CSR的两个缺点,服务端返回的html对SEO非常友好,且减少了用户看到最终UI的时间。
     
    SSR过程中有一个关键步骤称为Hydration (水合),主要包括:
    • 基于服务端的静态HTML在内存中重新构建组件树
    • 初始化应用状态
    • 在对应的DOM元素上绑定交互逻辑,如:点击事件
     
    还有一个与SSR差不多的技术,称为Static Site Generation (SSG)。
    二者最大的不同在于服务端渲染HTML的时机:
    • SSG - 应用构建时预先生成,一般适用于内容基本不变的页面,如:博客文章
    • SSR - 用户请求时即时生成,一般适用于根据不同的标识动态生成不同内容的场景,如:社交动态
     
    当然,SSR也有缺点:
    • 服务端渲染前,页面所需的所有数据要提前获取到,这也会增加用户的等待时间
    • 水合过程要求客户端的组件树与服务端的组件树完全一致,这就导致了水合过程必须要等到对应的JS加载完毕才能开始进行
    • 水合过程启动后无法暂停,页面的所有组件要在一次水合中全部处理完毕后,用户才能开始交互
     
    Suspense for Server-side Rendering
    基于上述SSR中提到的缺点,React18提出了另一个优化方案 —— Suspense。
    Suspense新增了两个能力:
    • HTML流式传输 (HTML streaming)
    • 客户端选择性水合 (Selective hydration)
     
    HTML流式传输的大概流程:
    首次渲染:使用Suspense包裹的组件,在服务端渲染过程中会被忽略,取而代之的是一个占位组件(一般是加载提示),渲染完成后服务端返回携带占位的HTML
    后续渲染:当包裹组件的数据准备就绪时,服务端会完成后续的HTML渲染,然后再次返回HTML(通过inline script计算对应的占位位置)
     
    客户端选择性水合的大概流程:
    刚才提到,传统SSR中水合过程要等待页面的JS加载完成后才能开始,而通过代码分割 (code splitting)则可以实现按需水合。
    针对被Suspense包裹的组件对应的JS代码做分割处理,可以提前水合已准备好的组件,等到后续的JS加载完成后继续进行后续的水合,这样可以尽快使应用”活”起来。
     
    更进一步,React支持动态调整组件水合的优先级,通过在事件捕获阶段的监听,可以优先水合正在被用户交互的组件,改善用户体验。(过程动图查看原文即可,此处不再赘述)
     
    Suspense SSR的缺点及提出的疑问:
    • 虽说Suspense支持JS代码动态加载,但是客户端最终要加载的代码总量是不变的。随着功能的增加,代码总量也会越来越多,是否所有代码都是客户端需要的?
    • 水合过程只在客户端进行,对于无交互的组件是否有必要?
    • 所有JS逻辑都在客户端中进行,对客户端设备有一定性能要求,是否可以利用一下服务端更强大的处理能力?
     
    React Server Components (RSC)
    基于上面针对Suspense SSR提出的几个疑问,React推出了RSC的架构,旨在最大程度上同时利用服务端与客户端进行UI呈现。
     
    RSC作为一种新的渲染架构,引入了双组件模型,分别为:
    • Client Components
    • Server Components
     
    Client Components:
    与讨论RSC之前所说的普通React组件一样,这些组件基本在客户端渲染 (CSR),但同时也支持在服务端SSR时渲染一次到HTML中,这些组件可以访问客户端环境,如:state、effects、事件监听/委托、geolocation以及localStorage等。
     
    关于Client Components更多细节参考Next.js文档。
     
    Server Components:
    RSC中新提出的一种组件类型。这些组件只在服务端渲染执行,不会下载到客户端中。
    带来的好处有:
    • 零bundle文件大小,客户端不需要下载这部分组件的代码
    • 支持直接访问服务端资源,如数据库、文件系统
    • 数据获取更高效,没有了客户端请求服务端的过程消耗或者可能存在的串行请求行为
    • 服务端层缓存,在后续的请求或不同的用户中可以复用
    • 首屏加载速度快以及FCP得分高,服务端直出最终页面
    • 与SSR一样,对SEO友好
    • 高效的streaming,支持分chunk渲染,用户可以尽快看到页面
     
    关于Server Components更多细节参考Next.js文档。
     
    RSC首次加载的渲染生命周期:
    1. 浏览器请求页面,Next.js App Router根据URL匹配对应的Server Components (SC),通知React开始渲染
    1. React渲染SC及其所有子SC,结果转换为一种特殊的JSON格式,称为RSC payload;检测到Suspend包裹的组件时,会使用占位符替代
    1. 同时,Client Components (CC) 开始准备后续要水合要用到的指令 (instructions)
    1. Next.js 在服务端使用RSC Payload与CC水合指令生成HTML,并流式返回给用户
    1. 同时,Next.js 也会流式返回RSC Payload
    1. 客户端接收到响应后,使用RSC Payload与水合指令进行渐进式 (progressively) UI渲染
    1. 所有SC与CC的渲染完成后,用户看到最终界面
    1. CC进行水合,激活组件的交互逻辑
     
    RSC更新的渲染生命周期:
    • 浏览器重新请求指定UI,如:路由刷新
    • Next.js 处理请求,匹配对应的SC,通知React渲染组件树,与之前流程一样得到RSC Payload与水合指令
    • 不生成HTML,直接流式返回RSC Payload给客户端
    • 客户端接收到新的payload后,开始重新渲染
    • React对比调和(reconcile)前后两次渲染结果(JSON比较),在保持原组件状态的基础上,更新DOM节点
     
    碎碎念
    个人用下来,体验并没有想象中好,不仅带来了更多的心智负担,也增加了生态上第三方库适配的工作。虽说的确解决了一些问题,但是带来了更多的问题。
    都说Next.js推RSC是出于商业化考虑(Vercel集成),也可以理解吧,纯粹的技术向企业基本不可能存在。
    或许,后续可以尝试一下Remix,据说写起来比Next.js舒服太多~
     
     
     
     
     
    Without You (Starlyte Remix)WebSocket vs Server-Sent events 阅读笔记
    Loading...