Flutter 应用框架Fish-Redux正式开源,对比Flutter-provide和Flutter-redux,闲鱼团队的Fish-Redux的完善的设计原则和UI数据逻辑分治的核心思想,成为整个框架的灵魂。
友情提示:阅读本文大概需要 30分钟
前言
跨平台、高性能的渲染引擎逐渐成为大前端领域的一个热点,作为其中的明星Flutter,有极大的机会成为下一代跨端解决方案,闲鱼重磅生根Flutter, 推出了2亿用户背后的应用框架Fish-Redux。
应用框架的设计原则和分层架构思想,闲鱼的Fish-Redux基于ReduxJS作出诸多改良,成为一款热门的Flutter状态管理开源框架。
Flutter技术栈背景
Flutter是谷歌推出的一个高性能跨平台渲染方案,主要有三个特点:
1. 原生性能
- 渲染方式、AOT、无锁GC
它主要用过原生的方式渲染,从分层的角度,无论是Android还是ios,都是基于相同一层的scale,在Release模式(Flutter有四种运行模式:Debug、Release、Profile和test)下会使用AOT预编译代码为机器码,然后相当于得到一个最短的一个渲染管线和更好的性能。
2. 快速开发
- 亚秒级、有状态的热重载
JIT的模式带来更快的启动体验,相对于native,我们修改一处代码,flutter可以快速的实时更新和展现、实时的响应,也许只需要1-2秒之间就能得到一个快速的热重载。
3. 统一的应用开发体验
- 两端一致的开发方式,MD和IOS风格
目前跨平台方案三驾马车:
1. 基于浏览器
目前基于浏览器的跨平台也做得越来越好,自然管线也越来越短,与native的一些技术手段来实现性能上的相互补充。
2. 类似RN、WEEX
上层通过面向前端友好的UI,下层通过native的渲染形式,H5与native相互补充来达到更好的用户体验,这也是一种很好的解决方案。
3. Flutter
从底层就承担跨端的任务和渲染方式,从目前来看,从技术的实现和方案的成熟度、产品的性能方面比较,Flutter有很大可能成为下一代主流跨平台框架。
Fish-Redux设计思路
在FR诞生之前,闲鱼团队初次使用Flutter遇到的一些问题:
这些常见问题,终于导致团队开发效率降低、代码质量变差。当出现这些问题时,我们复盘就可以知道一旦出现这种代码难以维护的问题,一般来说都是因为在软件层次里面缺少了某一层,导致了这些问题变得越来越复杂。这个时候我们就需要寻求那一层的设计来帮助我们解决之前遇到的各种小问题,简单来说,我们可能需要一层应用框架,来衔接Flutter和我们的上层业务之间,通过一个框架来使得我们遇到的问题能够统一地得到管理和解决。
在设计Fish-Redux之前,闲鱼团队也层对业界已有的框架进行过考虑和筛选。
1.业界方案-BLoC
Business Logic Component,BLoC,由谷歌开发推出,它的思路是把UI和逻辑分离,并且UI可以分得很细,整个方案由一定的分治关系;但是逻辑是统一的,这样做的优点是逻辑和UI分离、便于测试、一定的逻辑重用。缺点是没有办法对逻辑做更进一步的分治,虽然UI可以分治,但是逻辑的不可分治问题会随着业务逻辑的增大而复杂,最终变得庞大而难以管理。
2.业界方案-Redux
在前面的文章我也有介绍过,Redux是一款状态管理库,并且在闲鱼推出Fish-Redux之前,谷歌推出了Flutter-Redux这个方案,它与前端熟知的ReactJS社区里的Redux方案几乎一致,但是基于 Dart 和 JS 语言上的差异,它没有做到把一个Reducer 变成若干个Reducer一层层分治的效果。在谷歌的Flutter-Redux中,它的工作流程如下图所示:
它有唯一的一个store,直接对应下面的view,通过action的形式将数据流驱动起来,优点很明显,就是集中的数据管理、方便观察并且容易调试,并且有Middleware中间件机制更加相对容易拓展。但缺点是 把数据和逻辑集中了,但是很难把这一块的东西分治出来,在庞大复杂的业务中更应该将UI和数据逻辑分离开来,不能只是将UI分治了,而逻辑还混在一起,如果这样也会导致最终项目难以维护。
Fish-Redux设计原则
1. 适合
在软件设计阶段,每一层在叠加的时候,往往是为了解决特定的问题。以闲鱼的详情页面为例,商品详情页有很多个组件组成的,其中有很多数据是组件之间需要共享的,其中一个组件修改了数据,其他的组件需要实时的感知,基于这样的考虑,它就需要一个很健全很敏捷的状态管理的机制,而相对的像HelloWorld这样的demo不需要状态管理,仅仅原生的api ui就能够去实现。
此外还以闲鱼的宝贝详情页为例,它的很多类目,比如普通宝贝、拍卖宝贝等等,每个类目的之下有一些是有共性的,有些是有特色的一些组件,为了让这些得到更高程度的复用,为了更加合适的共享这样共性数据,我们就需要有一个分治,并且是一个可插拔的组件系统。比如说闲鱼的普通宝贝有10个通用组件和3个特色组件,拍卖宝贝只有8个通用组件和5个特色组件,合适的顶层软件架构,可以通过可插拔的组件系统,能够帮助宝贝详情快速的组件并上线。
当一个项目逐渐堆积的时候,我们就不可避免的将展示部分和逻辑部分分离开来,在解决适合闲鱼场景的时候,就需要把代码进行一个合理的解耦,此外还需要一个比较好的性能,闲鱼团队对每个上线的页面的性能指标都是非常严格的,每次改版之后,性能不可以有明显的下降,通过这一层的优化,页面性能应得到更好的提升。
2. 足够简单
在足够简单情况下就能满足业务诉求、体现出更好的性能,这是最好不过的了。这里的足够简单指的是希望它的api足够简洁简单,只需要一两个 API 就能让页面 work 起来是比较理想的状态了,比如 fish-redux 其中一个核心的 API 就是 dispatch ,通过 dispatch 就能驱动出一个 component 里所有的数据流的一个变换,甚至组件和组件之间通信,页面与页面之间的通信仅仅需要一个 API 就能够去完成。
此外还需要一个更加简单的规范的编程模型,我们可以把所有的编程模型统一起来,比如一个函数式的编程模型,它可能是一个更加简单的函数模型,在实际累业务代码的时候,我们在写核心的那几个函数,让它遵循一定的签名规范,这个事情就能 work 了,这样做起事来会更加事半功倍。
最后还有框架里提供的类的对象能够简单,我们希望提供的是最小级的类,不应该把框架不应该做的事情做掉。就比如fish-redux的源码没有一句调试代码或console,这些事情应该又开发者去定义,而不是由框架本身去做多余的事情。
3. 便于演进
做框架做工具,绝不是一蹴而就的事情,而是一个长期演进并优化的过程,在闲鱼团队发布fish-redux之前,这个框架在内部已经经过了3个版本的迭代和优化,在团队内部第一个版本FR的时候,是完全基于Flutter-redux的,完全继承有其优点,但是没有根本解决分治的难题;第二版本想要分治的效果,于是就做了一个决策,对 redux 分离,将一个redux分离成多个redux,这样相当于 component 都有一个 独立store 驱动,也改了其中redux的签名,这个版本也能 work,但是这个使用范围就变得狭小,适用范围不大,于是在此基础上优化出第三个版本,同时解决了 redux 的集中、component 的分治的问题。
Redux数据管理
Redux本身是像OP这样的数据管理,这部分在前面的文章有过详细介绍,这里不再赘述,具体解读可以参考前面的文章(点击链接即可跳转到文章)。
参考文献
Fish-Redux 视频地址:https://alivideolive.taobao.com/h5/liveDetail/ff36146a-b106-48f0-8cff-246fa0b62d50?code=6613447285c433f6a7002ad80b913de5&state=dingtalk
最后
今天的 Fish-Redux 设计原则 就分享到这里,有兴趣的同学可以回放 吉丰老师的 直播以及 Fish-Redux 的源码,祝各位在学习 flutter 路上越来越顺畅,欢迎大家留言,谢谢 ~