从 Web 页面渲染的发展过程来看,可以分为 3 个阶段: - 后端渲染 - 前端渲染 - 同构渲染 后端渲染应该都很熟悉,最典型的是 PHP,这种模式是瘦客户端模式,后端将数据渲染成HTML传输给浏览器,浏览器渲染CSS、DOM和JS。 前端渲染是现在的主流,从 Backbone、Angular、React 的流行开始,是胖客户端模式。只需要Nginx之流的HTTP服务器,就能撑起SPA的应用,Github的Page服务器等等都可以托管。当前端担当了许多的业务和交互,前端渲染就变得非常复杂,这种复杂是需要代价的,1:首次加载慢,2:无法 SEO 优化。 Isomorphic 在保持客户端很胖的情况下,让后端也胖起来,事实上这是一套完美的解决方案,解决了前端渲染的弊病,又保持前端交互不变。 像 NextJS 之类的框架,在 React 组件的基础上,提供了脱水和覆水的能力,这种方案简单来说,就是在服务端将组件都转换为字符串,但是事件之类的无法转换,怎么办呢?就是在服务端先将 state 脱水,然后在浏览器端将 state 覆水。这样,同一套代码在前后端做的事情其实是不一样的。React 在后端执行一遍,又到前端执行一遍,这样,造成Next.JS只有 272/QPS,React startar kit可以达到1200QPS,但是组件的复杂度上升QPS下降。 这种 Isomorphic 解决方案是不完美的,React 在后端算是一个巨大无比的库,肯定会拖慢执行速度。 > 创世记 1:11 神说,地要长出青草,和结种子的菜蔬,并结果子的树木,各从其类,果子都包着核;事就这样成了。 不管 React 是否提供后端渲染的能力,应该关注是否真的需要将 React 放在后端执行,凡事都应该各从其类,后端只做后端需要做的事情,如提供 API 能力,模板渲染能力,任务调度等等。而前端只关注交互。 Isomorphic 模式的渲染因为无法渲染事件,所以才会做脱水和覆水,但是如果后端不做渲染组件的事情呢?脱水和覆水是否就可以更轻量级了?根据后端渲染的经验来看,只是将数据填充到模板进行渲染。 > 在抽象代数中,同构指的是一个保持结构的双射。在更一般的范畴论语言中,同构指的是一个态射,且存在另一个态射,使得两者的复合是一个恒等态射。正式的表述是:同构是在数学对象之间定义的一类映射, 它能揭示出在这些对象的属性或者操作之间存在的关系。 Isomorphic是同构同态的一种架构,其实这种方案是非常棒的,只是在追求QPS最大化的情况下,就不得不考虑另外一种方案,Monomorphic是同台单射的模式,就是将后端处理好的数据传给前端。这些数据包括 Assets 静态文件,SEO 优化相关的 Meta,以及前端需要的 Initial state 数据,特别是 Initial state,相当于 Isomorphic 的状态脱水数据。这种解决方案比 Next.JS 之流快 10 倍以上。