减少平台差异性的重要性
在过程中,减少不同平台之间的差异性是非常关键的。这样做不仅可以降低各平台特有的负担,还能让过程更加顺畅。无论是从用户体验还是效率的角度来看,减少平台差异性都能带来显著的好处。
提高研发效率的关键
研发效率的提升不仅仅依赖于人效比的提高,还需要在各个环节中优化流程。从编码、调试到运行和测试,每一个环节的效率提升都能为整个项目带来巨大的收益。因此,团队应该时刻关注如何在这些环节中提高效率。
原生性能与用户体验
最终的研发产物应该具备与分平台原生技术一样的性能表现和用户体验。用户在使用产品时,不应该感受到任何性能上的差距。这就要求团队在技术选型和实现过程中,始终以原生性能为目标。
易学的可控技术栈
跨平台的技术栈应该具备良好的学习曲线,能够让更多原生的人员快速上手。同时,无论是从技术还是商业角度来看,技术栈都应该是可控且安全的。这样才能确保项目的稳定性和可维护性。
小程序技术栈的适用性
那么,小程序技术栈是否能够满足这些要求呢?微信小程序采用了以前端技术栈为主的方案,框架上抹平了许多平台差异性,业务也可以随时动态部署更新,体验和性能也比较接近原生。随着小程序生态的发展,还出现了更多丰富的插件扩展机制、自定义组件机制和第三方框架。小程序作为微信团队内部自主研发的框架,已经是一个非常优秀的跨平台框架,满足一般的业务需求是没有问题的。
小程序与微信客户端的结合
微信小程序采用了以前端技术栈为主的方案,框架上抹平了许多平台差异性,业务也可以随时动态部署更新,体验和性能也比较接近原生。随着小程序生态的发展,还出现了更多丰富的插件扩展机制、自定义组件机制和第三方框架。小程序作为微信团队内部自主研发的框架,已经是一个非常优秀的跨平台框架,满足一般的业务需求是没有问题的。
小程序技术栈的挑战
然而,当我们以“小程序技术栈作为客户端跨平台技术”这一命题展开,关注其中的一些细节时,也发现了问题。比如,在字体一致性体验问题上,微信小程序使用了自己的渲染体系,与原生客户端的视图渲染体系不同,导致在某些平台上无法跟随系统字体保持一致,体验上会有较为明显的割裂感。
复杂场景下的性能问题
在大量的图片和视频混排的场景下,会出现一些掉帧现象,尤其是在中低端机上较为明显。在图片滑动等连续过程中,会偶尔出现卡顿的情况。并且受目前小程序框架所限,视频、图片的全屏显示效果也不够理想。
基于小程序技术栈的跨平台优化
微信小程序的系统架构分为两部分:视图端通过小程序的框架将用户采用的信息处理成元素,最终交给渲染;端运行用户编写的逻辑,并且可以调用具有微信开放能力的。逻辑和视图分离,通过事件和数据彼此之间建立联系。
基于原生渲染的优化方案
原理上我们可以将用户描述的信息,转换成系统原生的组件。行业里面早有实践,受到这类框架的启发,我们将小程序的视图端进行了一些改造,在平台上我们出小程序框架中的信息和所有的样式,在层逐一的去解析映射成原生的组件。但原生体系并不能完全的表达过于复杂的样式,因此前期只支持了部分的特性。
跨平台模块的实现
我们初步方案当中有太多的实现一开始是用去做的,考虑平台兼容问题,为了方便移植到其他平台以及可以更低成本的更换渲染模块,我们就将原来解析和样式的实现单独抽离了出来,形成一个的跨平台模块。最终选择了++实现的-模块,由-去做跨平台的小程序体系处理器,完成和的解析、布局计算,同时执行的功能由8或者来完成。
原生组件的性能提升
采用原生组件的方案确实在体验和性能方面能够带来不错的提升,在2的机器上我们测出,帧率方面比提升了27.5%,内存也可以下降14%~23%。但随着我们要将该方案推广到各平台的时候,我们意识到需要在各个平台去做适配是一个巨大工作量的事情,而且后续的维护成本也将无法预测。
跨平台渲染方案的选择
基于的渲染满足不了性能和体验的要求,基于原生渲染又会带来高维护成本问题,我们需要一个跨平台的渲染方案来解决。在研究各种可能的方案的时候,再次走进了我们的视野。是为跨平台打造的高性能应用框架,受到了很多同行的关注,但如果按照我们设定的微信跨平台的目标来看,并不完全符合,使用会对现有同学造成额外的学习成本,所以一开始我们并没有将作为客户端跨平台的候选。
的优势
但当我们的问题重新设定为“寻找一个跨平台的高性能渲染框架”时,就逐渐体现出了各项优势。从一些经典的案例中看到,具有非常不错的性能水平。这组数据是我们在平台测出的,和的对比数据,数值越高表示性能越好。同时另一个有意思的情况是,随着版本的提升,性能表现会越来越好,也说明的人员在不断地优化性能表现。
基于的小程序框架渲染优化方案
在这个架构下,我们就将层的-专门的作为小程序的体系处理器,将信息布局计算好再提交给抽象的后端去渲染,-作为小程序的框架和渲染器的中间层,集中的在++层去处理与相关的复杂特性。渲染端就可以基于特定的协议和接口专注将元素转化为组件,最终绘制出来。通过结合和-,我们把实现代码收敛在,++和上,进一步简化了基于小程序技术栈实现跨平台业务的框架维护成本。
通信的优化
基于的体系下可以在层通过提供的接口注入一个,就可以得到一个扩展的,调用的时候经过8最终反射到上面。在上面也是类似的实现,这种方式第一是会带来平台相关性的实现;第二是调用路径较长。所以在这个问题上,我们最终使用了方案,将原先依赖平台的实现直接下沉到++,去实现对象的扩展,既可以解决跨平台的问题也能带来性能的提升。
2模块的实现
所以我们对进行了一些改造,增加了一个2的模块,暴露出部分的++接口,使得外部的动态库可以基于这些接口通过调用到的接口。在的运行环境中++和之间就可以像调用自身的接口一样调用彼此的接口。而且在模式下会被编译成机器码,所以++和的调用会非常的高效。不需要将数据编码成消息和跨线程一系列的复杂流程,而是直接在内存栈上操作数据。2相比于的方案提升多少呢,同样的测试案例,一秒内通过2可以完成三十多万次的相互调用,可以说是极大的提升了通信效率。
2实现原理
但这个/++接口必须要先注册到当中,不然就无法查找到符。另外,在动态部署()方面虽然没有提供官方的支持,但是在借助于2下能够做的事情就很多了,但这并不在本文的讨论范围。至此不同语言环境中的调用通信问题有了比较高效的解决方案。
整体架构的优化
使用简化的/描述的信息,经过小程序前端公共库处理成描述,通过接口传递给-去解析和节点(+)。-在完成布局计算之后将元素信息通过2的接口发送到端,层直接将布局计算好的元素描述成渲染节点,交给去绘制。整体上来讲我们把代码收敛在,++和上,所以在跨平台方面会极大减少额外的负担。对小程序的者也不会带来任何的改变,面向者的依然是原有的小程序技术体系。
具体问题的解决方案
字体不一致问题:通过自定义实现跟随系统原生视图字体;视频、地图等同层渲染:官方提供了一种机制,通过的方式将平台渲染的同步到的渲染体系中来,保证同一时刻界面上仅存在一种视图体系;文本输入框:官方提供了较为完整的输入框控件;性能提升:相比在低端机上有可见的性能指标提升;减少重复资源投入,多平台维护:基本上只需要维护和++代码,平台相关代码可以最小化。
未来展望
当然,目前阶段在性能上还存在很大的进步空间,相比-方案的各项性能指标并未达到最佳,仍需要充分的发挥的特性,提高这套框架整体的可用性。注:由于阶段方案变化较快,此处对比数据并未在同样的设备下测定,仅以相对渲染提升为例做为说明。
常见问题解答
1. 小程序在产品上是否会有什么改变?是否会放弃渲染转向渲染?2. 使用渲染的这套方案在遇到复杂属性的时候表现如何?3. 2模块是否支持传递对象和自定义数据,是否考虑开源或者开放出来供大家使用?4. 端接入会带来包大小的变化,以及无法,你们对的接入是怎么做的?