发布时间:2023-12-12 13:30
本文详细介绍了响应性数据系统在 Tubes 中的运用,以及响应性数据系统的三种不同设计与原理。
Tubes是一套面向C端搭建场景,支持灵活扩展、极致性能和高稳定性的终端渲染解决方案,目前广泛运用在淘宝、天猫,包括:双11、618会场、淘宝新人版首页等业务场景。
介绍
响应性数据系统指的是程序在使用系统提供的数据的同时会自动订阅自己所使用的数据,被订阅的数据发生变化时使用了(订阅了)这个数据的程序会对数据的变化做出响应。
响应性是 Vue.js 最具特色的特性(之前叫响应式,Vue3给翻译成响应性,我认为响应性这个词整挺好),不过 Tubes 的响应性原理和 Vue.js 略有不同。
响应性数据系统在Tubes中发挥的作用
Tubes 为什么需要响应性数据系统,这来源于一个重要的业务问题:“如何解决会场分屏渲染问题”,站在技术视角要解决的问题是:“Tube多次执行的设计问题”。
正在读文章的你可能不了解Tubes体系,不清楚什么是Tube,没关系,你可以把问题想象成:如何解决 Express.js 的中间件多次执行、如何解决 Webpack 的Loader多次执行。
分屏渲染指的是在搭建体系中,产出的页面会先渲染首屏的模块,再渲染次屏模块。在Tubes体系中,从第一个Tube开始执行,执行到最后一个Tube则完成一次渲染(这与 Express.js 的中间件机制有点类似,一个请求进来从第一个 Middleware 开始执行,执行到最后一个Middleware结束),如下图所示:
从第一个Tube执行到最后一个Tube则完成一次模块的渲染。在会场分屏渲染的场景下,通常第一轮执行完毕表示完成了首屏模块的渲染。那么想要渲染次屏模块,只需要再执行一轮Tube就可以将次屏模块渲染出来。那么问题来了,Tube多次执行的机制如何设计比较优雅?
我们设计了两种方案:“方案一:基于循环系统实现”、“方案二:基于响应性数据系统实现”。下面我们对比下两个方案的区别:
基于循环系统,Tube可以一圈一圈执行。第一圈渲染时,Tube开发者可以在内部调用API通知 Tubes-Engine 本轮执行完后还需要再执行一轮。通过这样的机制,实现第一圈渲染首屏模块,第二圈渲染次屏模块。
这里的问题是由于并不是所有Tube都需要执行多次,因此 Tubes-Engine 需要为Tube提供一些属性和方法(例如:当前执行的圈数、once方法等)方便 Tube 根据 “圈数” 做一些逻辑、或者使用 once
声明自己只需要在第一轮执行一次,后面的其他轮次不参与执行。
其实只有和“首屏”、“次屏”渲染逻辑强相关的Tube需要多次执行(举个例子:env tube的逻辑是初始化一些环境信息,比如是否是Android或者iOS,PC还是Mobile,这个逻辑只需要在第一轮执行时执行一次就可以),在基于循环系统的实现下,不需要多次执行的Tube就需要开发者明确声明这个Tube只需要执行一次(就是说,如果开发者判断自己的Tube只需要执行一次,那么他需要为这个Tube做一些额外的处理)。
现在我们总结下这个方案的优缺点:
优点: Tubes-Engine内部实现简单(意味着不容易出错)
缺点:
Tube开发者需深入理解Tube运行机制(轮圈制)以及背后为什么设计成“轮圈制”
每个Tube,都需要处理轮圈制相关的逻辑,例如:
只需要执行一次的Tube:需要使用once声明自己只需要执行一次
需要执行多次的Tube:需要根据圈数来判断本轮做什么事情,以及是否需要再来下一轮并调用API通知 Tubes-Engine 再执行一轮。