最右 JS2Flutter 框架——开篇(一)
1、背景
今年年初,我们在InfoQ发表了一篇题为Flutter动态化在最右App中的实践[1]的文章,主要讲述了最右实践Flutter动态化的方案,文章发布至今越来越多的业内同学联系到我,想了解更多关于最右Flutter动态化的细节,尤其是iOS端的JS2Flutter框架,于是就有了展开系列文章详解JS2Flutter框架的想法。
这篇文章作为JS2Flutter框架的开篇,后续将逐步介绍该框架的渲染机制、通信机制以及依赖于Vsync机制的动画和小游戏的实现等核心技术点。一来分享实践经验,供感兴趣的同学参考;二来算作对自己在这个工作过程中的总结。
2、设计理念
最右做Flutter动态化的初衷是要实现小程序和小游戏的能力,满足增量独立的业务场景,为最右提供更多可能的技术选型。比如一些对交互体验要求比较高的活动或者小游戏就很适合这种方案,我们不打算做最右主版本功能的迁移(成本过高也没必要),而是稳健延伸App的能力,去承接一些非核心的业务场景。
在做这件事情之初,我们也确定了这样一些设计理念。
对Flutter开发者透明,无额外的学习成本,零成本享受Flutter生态资源。
Flutter侧只负责UI渲染,控制逻辑在JS侧。
渲染效率和灵活性之间的取舍更向效率倾斜。
3、JS2Flutter的诞生
3.1 方案选型
做Flutter动态化面临的第一个问题就是技术方案选型,产物替换的方案是最简单直接的,最右在Android端就是采用这种方案,但是由于苹果开发者协议的规定,不允许动态更新、运行可执行代码,这条路在iOS端走不通。另外通过AOT搭载JIT这种方案,也面临类似的风险。剩下一些可能的方案就是,静态解析Dart语言生成UI描述或者类似RN运行时生成UI描述,前者最大的问题是工程量的庞大,对逻辑动态化的支持难度颇高,在最右这样一个创业型的团队,显然没有足够的人力来完成这件事情,所以我们选择了类似RN的方案,只不过N不再是Native了,而是Flutter。RN是通过JS控制Native渲染,我们要实现的是通过JS控制Flutter渲染。
3.2 对开发者友好
类RN的方案,需要依赖JS来实现逻辑控制,怎样才能不影响Flutter开发者的开发习惯,并能享用Flutter的生态资源,这是框架诞生前期思考的核心问题。
我们借鉴学习了Flutter Web项目的实现思路,借助dart2js这个强大的工具实现了Code In Dart,Compile It To JS。通过dart2js,我们实现了对Flutter开发者透明,可以让开发者保持原有的Dart开发调试习惯,零成本支持Flutter Plugin,并且我们开发了IDEA插件,能够便捷的编译生成双端动态化产物。
3.3 Hello World
我们从最简单的Hello World讲起:
在这个过程中,我们需要完成哪些事情呢?
1.编译成JS
2.动态下发
3.运行JS
4.把Text类信息和内容(Hello World)传递给Flutter
5.Flutter解析构造出真实的Text并渲染
前三步没啥好说的,第四步其实就是UI描述的建立,想要让Flutter渲染什么类型的Widget,我们需要通过JS告诉Flutter,所以这一步我们要把所表达的信息数据化。比如这样:
第五步我们把拿到的数据解析出来,构造出真实的Text('Hello World')。当然第四五步之间还涉及到数据的传递,也就是需要建立JS到Flutter的通信渠道,JS和Native之间通过JSCore建立通信,Native和Flutter通过PlatformChannel建立通信,这样就能完成JS和Flutter之间的通信。
3.4 框架诞生
想想如果需要实现的Widget越来越多,不同场景的通信也有不同的需求,我们应该如何去维护这一套体系,JS2Flutter框架应运而生。从Hello World的实现过程我们不难理解,框架必须包含这几部分,一部分提供镜像的Flutter Widget,负责构建Widget虚拟树,并数据化传递给Flutter;一部分负责解析传递过来的数据,构建出真实的Widget树;两者之间还有一部分去做通信渠道的关联,以及提供JS的运行环境,补全JS的一些能力等。
随着框架的不断演进和完善,形成了下图呈现出来的结构。
3.5 框架详解
如题,本文作为JS2Flutter框架的开篇,起到提纲挈领的作用,后续会完成以下系列文章的讲解:
一、最右JS2Flutter框架——渲染机制
二、最右JS2Flutter框架——通信机制
三、最右JS2Flutter框架——动画、小游戏的实现
4、实践经验与成果
每一次的业务落地都是对框架的检验,从业务实践中,逐步发现框架的问题,促进框架的完善。业务实践不仅能检验框架,还能促使框架之外的一些工具链诞生,逐渐完成流程自动化,提高研发效率等。随着不断的迭代打磨,JS2Flutter框架自诞生至今,已经在数十个活动类需求和小游戏中得到了应用,也经受住了大流量的考验,在线上已稳定运行近一年。
下面是框架在2019年的最右五周年活动上落地的成果。
两端的体验都跟原生体验非常接近,非常流畅。iOS端在有JS2Flutter框架的前提下,也并没有明显的性能折损。
5、业界发展近况
目前已知的Flutter动态化项目有腾讯开源的MXFlutter[2],以及美团的Flap[3],这两个团队在动态化方向上的投入都很积极。从MXFlutter的2020 RoadMap里可以看到他们在开发者友好度方面树立了很明确的目标,开始支持业务由Dart开发,也有很多易用性方面的改进。Flap研发团队放出来的信息相对于去年来说更加丰富,这确实是一个庞大的工程,要建立起这样一套完整的体系绝非易事。
虽然都是去实现Flutter的动态化,但在实现方案上各个团队的差异比较大。
6、结束语
最右的动态化框架一直在不断演进,年初我们是基于Flutter1.9.1+hotfix.6版本,如今已经升级到Flutter1.17.2,最右在Flutter动态化方向上的投入是很积极的,也积累了很多经验。JS2Flutter框架是最右在探索Flutter动态化之路上的技术沉淀,后续将在系列文章中展开详解,感兴趣的同学可持续关注。
7、参考文献
[1]:Flutter动态化在最右App中的实践 https://www.infoq.cn/article/MIa5AN2JE51uor4JeiPG
[2]:MXFlutter https://github.com/mxflutter/mxflutter
[3]:美团外卖Flutter动态化实践 https://mp.weixin.qq.com/s/wjEvtvexYytzSy5RwqGQyw
评论