Single SPA中如何单独为footer应用实现服务端渲染(SSR)
现有配置与需求
你当前的Single SPA路由布局配置(routes.html)如下:
<single-spa-router> <redirect from="/" to="/home"></redirect> <div id="wrapper"> <div class="wrapper-content"> <div class="layout-content"> <application name="@ppbet/layout-app"></application> </div> <div class="main-content"> <div class="layout-left-content"> <application name="@ppbet/layout-left"></application> </div> <div class="center-content"> <route path="home" exact> <application name="@ppbet/home-app"></application> </route> <div class="main-content-custom"> <footer> <application name="@ppbet/footer"></application> </footer> </div> </div> <div class="layout-right-content"> <application name="@ppbet/layout-right"></application> </div> </div> </div> </div> </single-spa-router>
核心诉求:仅让@ppbet/footer(React组件类微应用)在首屏完成服务端渲染,其余微应用保持客户端渲染,不需要启用全应用级SSR。
官方提供的全应用SSR方案会强制所有首屏匹配的微应用走服务端渲染,不符合需求;single-spa-html的加载逻辑完全运行在客户端,无法实现首屏服务端直出效果。
落地实现方案
方案1:宿主模板直出+客户端hydrate(改造成本最低,优先推荐)
- 改造宿主应用的服务端逻辑:在返回入口HTML模板前,单独引入
@ppbet/footer对应的React组件,调用服务端渲染方法生成DOM字符串,直接插入到模板中<footer>标签的内部位置。 - 调整
@ppbet/footer微应用的生命周期逻辑:- mount阶段先检查挂载容器下是否存在服务端直出的DOM(可以给服务端直出的根节点加
data-ssr-mounted="true"标记做判断) - 如果存在已渲染的DOM,直接走hydrate流程:React18使用
hydrateRoot,React17及更早版本使用ReactDOM.hydrate,不要重复调用render方法 - 如果不存在(比如本地开发环境、客户端路由跳转后重新挂载的场景),走正常的客户端render流程
- mount阶段先检查挂载容器下是否存在服务端直出的DOM(可以给服务端直出的根节点加
- 不需要修改现有路由配置里的footer微应用声明,也不需要启用single-spa的全量SSR能力,其余微应用的加载逻辑完全不受影响,首屏可以直接看到footer内容,不会出现加载空白。
方案2:Single SPA选择性SSR渲染
- 如果你已经搭建了基础的single-spa SSR运行环境,可以不用开启全量SSR,只在服务端的微应用匹配列表里单独加入
@ppbet/footer。 - 服务端收到请求后,只触发footer微应用的服务端生命周期,拿到渲染结果后拼接进返回HTML的对应footer位置,其余微应用不做服务端渲染处理。
- 客户端侧footer微应用的hydrate逻辑和方案1一致,其余微应用正常走客户端加载挂载流程即可。
- 这个方案适合已经有部分SSR基建的场景,不需要在宿主服务层单独写React渲染逻辑,注意不要把其他微应用加入SSR渲染列表,避免不必要的服务端性能开销。
方案3:独立静态片段嵌入(适合低交互场景)
- 如果footer本身交互很少、内容更新频率低,可以直接把footer单独部署成SSR渲染的静态HTML片段,在宿主HTML中直接通过服务端include、或者客户端初始化前同步fetch的方式插入到footer位置。
- 这种场景下甚至可以不用把footer注册为single-spa微应用,缺点是如果footer需要和主应用、其他微应用做频繁状态通信,样式隔离、通信逻辑的改造成本会高于前两个方案。
注意:不要尝试用single-spa-html实现这个需求,它的本质是客户端运行时动态拉取HTML片段并挂载,首屏返回的HTML中不会包含对应内容,无法达到SSR的首屏直出效果。
内容的提问来源于stack exchange,提问作者saikiran
相关产品推荐
相关产品推荐

