“前后端分离”在国内技术圈流行了十年以上,如今已经很少有人把它当成新概念讨论。但有意思的是,近几年随着服务端组件、岛屿架构等形态的出现,渲染逻辑又开始往服务端回流。回头看这段演进,驱动变化的从来不是某种风格的优劣,而是页面复杂度、团队协作方式和终端数量这三件事的实际变化。
服务端渲染:老而弥坚的形态
模板渲染的流程很朴素:请求进来,服务端查数据、填模板、吐 HTML,浏览器直接展示。它的优势在今天依然成立——首屏快(HTML 直出)、SEO 友好、一套渲染逻辑、没有跨域和接口契约问题。对内容型站点、后台管理系统、对交互要求不高的页面,模板渲染依然是成本最低的方案。
它的极限出现在交互密度上升之后。页面里嵌入大量局部刷新、拖拽、实时校验、复杂表单状态时,模板引擎拼字符串的方式会让代码迅速变成意大利面;前后端职责纠缠在模板里,改一个按钮的展示逻辑可能要动后端代码并重新部署。团队变大后,前端和后端抢同一个文件、发布互相等待,协作摩擦指数上升。
分离的收益:并行与多端复用
前后端分离的本质是把”页面”拆成”数据接口 + 客户端渲染”两部分。后端只负责吐 JSON(或 gRPC、GraphQL 等形态的数据),前端在浏览器里拿数据自己组装界面。
最直接的收益是并行开发。接口契约定下来之后,前端用 mock 数据开发界面,后端同步实现逻辑,两边互不阻塞。联调不再是项目尾声的冲刺,而是贯穿全程的例行公事。前端也因此拿回了界面的完整控制权:路由、状态管理、组件复用、动效、离线能力,都变成客户端代码的一部分,可以独立测试、独立发布。
多端复用是另一个推力。同一套接口要喂给网页、App、小程序、开放平台,把渲染留在客户端、把数据抽成接口,是最自然的划分。后端从”为某个页面服务”变成”为多种终端服务”,接口的抽象层次被迫提高,反倒让业务逻辑更清晰。
分离的代价:契约、跨域与鉴权分散
分离没有免费午餐,代价同样具体。
接口契约成为新的协作边界。字段改名、类型变更、语义漂移,过去在模板里改一行就好,现在要动两端。没有契约管理(接口文档、类型定义、契约测试)的团队,联调阶段的”字段对不上”会反复消耗时间。契约一旦对外发布,就变成了承诺,废弃字段要走版本策略,不能想删就删。
跨域是浏览器给分离架构的见面礼。前后端不同源就要处理 CORS 预检、凭证传递、cookie 策略,网关层要为跨域配置付出额外的运维成本。开发环境还要处理代理转发,配置不对就出现”本地能跑、线上 401″的经典问题。
鉴权从”服务端模板里判一下”变成”每个接口都要鉴权 + 前端路由也要守卫”的两层体系。Token 放哪、怎么刷新、跨标签页怎么同步、登出怎么让所有端失效,每一项都是分布式会话的现实问题。过去一个 session 中间件解决的事,现在散落在网关、服务端校验、前端拦截器三处。
REST 还是 RPC:风格背后的关注点
分离之后,接口风格的选择浮上水面。REST 以资源为中心,URL 表示名词、HTTP 方法表示动作,天然适合 CRUD 密集、对外暴露、需要通用缓存语义的场景。它的优势是标准化程度高、任何语言任何工具都能消费。
RPC 风格以动作为中心,一个方法一个调用,参数返回值有强类型定义,适合内部服务间通信、对性能和类型安全敏感的链路。序列化更紧凑、调用更接近”函数调用”的心智模型,代价是生态偏内部、对外暴露需要额外的网关转换。
取舍的关键不是”哪个更先进”,而是消费方是谁。面向第三方、面向多端、需要缓存和可读性的场景偏向 REST;内部微服务、高频调用、对延迟敏感的场景偏向 RPC。一个系统里两者并存是很常见的现实,没必要强求统一。
接口版本管理:承诺的成本
接口一旦对外,改起来就是社会事件。常见的版本策略有 URL 版本(/v1/users)、请求头版本、以及”只加不改”的平滑演进。
URL 版本直白、好路由、好监控,代价是版本会无限繁殖;请求头版本 URL 干净,但调试和缓存语义复杂些。更务实的做法是默认”只增不改”:新增字段旧客户端忽略即可,删除字段要走双写过渡、公告废弃、统计调用量、确认归零再下线。
版本管理的真正成本不在技术,而在沟通。每个破坏性变更背后是若干个调用方的改造排期,没有调用方清单和废弃流程,版本管理就是空架子。
BFF:为终端量身定制的聚合层
多端复用推到一定程度会出现新问题:网页要的数据聚合度高(一屏拼五六个接口),手表端要的数据极简,App 要的字段和网页不一样。让所有终端消费同一套”通用接口”,要么字段冗余、要么来回补接口。
BFF(Backend For Frontend)是在后端和终端之间加一层”为某个终端定制”的服务:网页 BFF 负责聚合、裁剪、编排,终端拿一个接口就够。这层服务把”多端差异”从后端业务服务和前端代码里剥离出来,业务服务保持纯粹,前端保持轻量。
BFF 的代价是多了一个部署单元、多了一层转发延迟、多了一份维护成本。终端种类少的时候没必要上,终端种类多、聚合需求差异大时,它是把复杂度放在正确位置的手段。
SSR 回潮:不是推翻,是再平衡
近几年服务端渲染重新出现在主流讨论里,服务端组件、岛屿架构、流式渲染等形态不断出现。驱动这轮回潮的动因很实际:纯客户端渲染的首屏白屏时间偏长,对 SEO 和弱网环境不友好;前端打包体积膨胀到兆级,运行时开销不可忽视;一些内容型页面本来就不需要复杂的客户端状态。
新的形态并不是回到模板时代。服务端组件可以按组件粒度决定”在服务端跑还是客户端跑”,把数据获取放在服务端、把交互留在客户端,用构建工具自动拆分。它更像一次再平衡:把不需要客户端能力的部分还给服务端,把需要交互的部分留在客户端,用编译器而不是人力去决定边界。
从模板渲染到前后端分离,再到今天的服务端回流,架构风格始终在跟着页面复杂度、团队协作方式和终端形态调整。没有哪个形态是终点,能降低当前协作摩擦、匹配当前页面形态的选择,就是当下合适的选择。
评论(2)
已经推荐给组里新来的同事了。
有段时间天天处理这个问题,看到文章有点感慨。
请 登录 后参与评论。