导读
本文次要针对罕用跨端技术Flutter、ReactNative、Weex、H5,从技术特点、根本架构、编译原理、根本渲染流程等进行梳理剖析;以及一些常见性能问题如何优化解决,而后如何进行技术选型或在进行业务开发时抉择不同技术栈的逻辑是什么。

01
背景
在往年的麻利团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!

随着技术的倒退,产生了越来越多的端,如Android、iOS、Mac、Windows、Web、Fuchsia OS、鸿蒙等,而随着公司业务的倒退,呈现了越来越多的业务场景;作为APP开发人员,在日常工作中难免会碰到以下问题,如:1、UI设计师在进行UI审查时、测试同学在回归测试过程中、业务方在应用过程中,多少会发现端与端存在着差别,影响用户体验;2、同样的业务、同样的性能在不同的端上,须要每端投入资源去开发实现。而挪动互联网的倒退曾经处于早期,领导们越来越关怀投入产出。

与此同时,呈现了一些跨端的技术解决方案,能够实现一套代码在多端运行,解决业务倒退上的痛点,如Flutter、ReactNative、Weex、H5(注:小程序和其它基于DSL的计划暂不在本文探讨范畴)。而后对一些罕用APP进行了比照剖析,论断和预期统一,大部分都在应用跨端技术;Flutter和ReactNative使用率较高,Weex使用率绝对低一些,H5根本都在应用,应用多种跨端技术框架是一种常态。那么,它们都有哪些特点呢?

02 
四种技术栈特点介绍

了解,首先 MCube 会根据模板缓存状态判断是否须要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的构造,转换实现后将通过表达式引擎解析表达式并获得正确的值,通过事件解析引擎解析用户自定义事件并实现事件的绑定,实现解析赋值以及事件绑定后进行视图的渲染,最终将指标页面展现到屏幕。

图1-技术栈特点

通过图1,从性能、开发语言、渲染、包大小、社区、反对平台等方面梳理了它们的次要特点;不禁产生几个问题:为什么原生和Flutter性能更好?为什么ReactNative和Weex性能绝对较差?为什么H5页加载慢?这些性能问题该如何去优化,这是须要深刻理解的问题,上面将从根本的架构、渲染流程、编译运行原理等一起剖析。

03
基础架构介绍

3.1 Flutter基础架构介绍

ABM是Apple公司提供的iOS利用的散发渠道之一,与App Store平台不同,ABM是2019年10月才开始在中国区启动的一套全新的利用散发零碎,局部性能和企业账号相似,旨在为企业提供疾速、高效的形式来部署利用到企业领有的苹果设施。ABM与App Store两个平台的要害区别如下:

图2-Flutter基础架构

Google在2018年公布了Flutter 1.0,如图2所示,次要分为Framework层和Engine层;

Framework层:基于Dart实现,次要包含Text、Image、Button、动画、手势等各种Widgets,外围根底类库io、async、ui等package;基于Framework开发App,其运行在Engine层上,Framework和逻辑层都在基于Dart语言开发,对于开发而言,一切都是Widget,Widget是UI实现的根底;Engine层:基于C++、C实现;次要包含Skia渲染引擎库、Dart Runtime、Text文本渲染库等,而Engine层自带Skia渲染引擎,以此实现所有端的渲染展现对立,在Engine层适配平台差别和跨平台反对,实现更完满的跨端成果;Dart代码通过AOT编译为运行平台的二进制代码。也就是说Flutter不须要桥接,本人实现从逻辑侧和渲染侧的所有能力,和原生相似。这也是它性能突出的关键所在。另外Android自带Skia引擎,所以也使得在Android的的编译产物比iOS更小。除了反对挪动端外,还反对Mac OS、Windows等PC端和Web端,在新的Funchsia OS也反对Dart,应用Flutter作为UI框架。

对于Flutter Web,Framework层是专用的,意味着业务层能够应用此层的widgets实现逻辑跨端;但Engine层则不同,须要通过Canvas Render或者 HTML Render对齐Engine的能力。2022年5月Google IO大会公布Flutter 3.0,除了挪动端,更好的反对了Mac OS、Linux平台,也包含其它一系列优化和反对,大家能够多关注。

3.2 ReactNative基础架构介绍

ABM是Apple公司提供的iOS利用的散发渠道之一,与App Store平台不同,ABM是2019年10月才开始在中国区启动的一套全新的利用散发零碎,局部性能和企业账号相似,旨在为企业提供疾速、高效的形式来部署利用到企业领有的苹果设施。ABM与App Store两个平台的要害区别如下:

图3-ReactNative基础架构

ReactNative是Facebook于2015年开源,如图3所示,次要服务于Android和iOS两端,采纳React开发实现逻辑侧代码(也可利用于前端),采纳Redux实现状态治理,在APP中UI渲染、网络申请、动画等均由原生侧桥接实现;在这里理论运行过程中,js侧的dom会造成一个virtual dom,并通过bridge桥接将此dom构造传输到原生侧,原生侧会解析并映射到原生控件,造成原生的dom构造后,再调用原生能力进行渲染展现。

2021年ReactNative新版本对底层进行了重构,能够关注一下,如扭转线程模型,引入异步渲染能力,容许多个渲染并简化异步数据处理,简化 JSBridge等。

3.3 Weex基础架构介绍

图4-Weex基础架构

Weex是阿里2016年公布的跨端框架,如图4所示,Weex编译产物js bundle能够部署在服务端,APP加载完即可运行,也能够看出具备动静公布的能力;和ReactNative相似,Weex在理论运行过程中,js侧会造成一个dom,并通过Bridge交由原生侧解析,映射到原生控件再由原生能力进行渲染;Weex基于JS V8引擎,基于Vue设计,反对Android、iOS、Web三端。3.4 WebView基础架构介绍

图5-WebView内核基础架构WebView内核模块较简单,如图5所示,这里次要介绍WebView架构次要的几个局部:桥接协定是下层逻辑测与WebView的通信层,是JS和Native相互通信的能力层;

WebCore是浏览器加载和排版渲染页面的根底,次要包含资源加载、HTML解析、CSS解析、DOM解析、排版渲染等,JavaScript引擎是JavaScript解析器,JavaScriptCore是Webkit的JavaScript引擎,V8是Google的Blink的默认引擎;WebKit Ports是WebKit中移植局部,包含网络、字体、图片解码、音视频解码、硬件加速等模块;而后再往下也应用了很多第三方库,包含2D图形库、3D图形库、网络库、存储库、音视频库等;最底层是操作系统,反对Android、iOS、Windows等零碎。

3.5 编译原理剖析

Flutter反对Release、Profile、Debug编译模式。

Release模式即应用AOT预编译模式,预编译为机器码,通过编译生成对应架构的代码,在用户设施上间接运行对应的机器码,运行速度快,执行性能好;此模式敞开了所有调试工具,只反对真机。对于编译产物,iOS侧次要生成App.framework和Flutter.framework;App.framework为dart代码编译产物,Flutter.framework为引擎编译产物;Android侧次要在lib下减少了libapp.so和libflutter.so,libapp.so为dart代码编译产物,libflutter.so为引擎编译产物,不同的是在assets下减少了flutter_assets寄存援用资源文件。

Profile模式和Release模式相似,此模式最重要的作用是能够用DevTools来检测利用的性能,做性能调试剖析。

Debug模式应用JIT即时编译技术,反对罕用的开发调试性能hot reload,在开发调试时应用,包含反对的调试信息、服务扩大、Observatory、DevTools等调试工具,反对模拟器和真机。iOS侧次要生成App.framework和Flutter.framework,在App.framework文件夹里多了isolate_snapshot_data,kernel_blob.bin,vm_snapshot_data;Android侧也同样多了多了以上文件,但lib下少了libapp.so文件。

ReactNative整体分为逻辑侧和渲染侧,逻辑侧基于js引擎,会将基于React写的代码编译为JavaScript原生代码,再编译生成jsbundle文件,内置或下发到APP端运行;而渲染侧依赖于Android或iOS原生渲染,须要分平台编译对应的编译产物,而后公布到服务端或内置到APP。

Weex和ReactNative相似,weex会将源码编译为js bundle,这些js bundle能够部署在服务端,APP下载完js bundle后,通过js引擎构建虚构dom并通过桥接映射到原生dom,由原生渲染引擎进行渲染。

H5:以React和Vue为例,会将以框架开发的代码编译为JavaScript原生代码,即而后在浏览器或者WebView中执行;内核会先建设连贯、加载资源,而后解析、排版布局、绘制渲染出现给用户。3.6 根本渲染流程比照

图6-根本渲染流程比照

简略剖析渲染流程,基于Android和iOS原生开发APP,调用Framework框架层实现下层逻辑,通过布局绘制后间接调用零碎渲染引擎进行渲染展现;基于Flutter开发APP,会间接调用Skia渲染引擎进行渲染展现;不依赖于原生渲染。

基于ReactNative或Weex开发APP则不同,首先业务逻辑是基于React或Weex开发,而后会将js bundle包预置或下载到APP,而后将虚构dom通过bridge映射到原生控件,再调用原生渲染引擎进行渲染展现。

基于Hybrid计划开发APP,须要通过React、Vue等前端框架实现,首页要编译为JavaScript原生语言,而后通过链接在WebView或浏览器加载页面,要害的流程是连贯加载、解析、排版、绘制,最初再调渲染引擎进行展现。

通过以上所有剖析,能够答复后面提出的问题:

为什么原生和Flutter性能更好?主是都是通过布局绘制后间接调零碎或自带渲染引擎进行展现。

为什么ReactNative和Weex性能绝对慢?次要是须要下载js bundle包,并把js dom构造解析映射到原生,而下载和预置都比拟耗时,并且依赖原生进行渲染(ReactNative新版本升级了基础架构,据说有较大性能晋升,大家也能够关注)。

为什么H5页加载慢?次要因为连贯和加载比拟耗时,这里占大部分工夫,连贯和加载完当前根本就是WebView或浏览器本地能够实现的工作,前期优化也能够以此为切入点。

04常见次要性能问题优化

在理论开发过程中也遇到了一些性能问题,接下来进行简略介绍。

4.1 如何优化Flutter性能?

要害优化指标:页面异样率、页面FPS帧率、页面加载时长。

页面异样率(异样产生次数 / 整体页面 PV 数):通过 runZoned 与 FlutterError 两个办法,在异样拦挡的办法中统计异样的产生次数和堆栈数据。

页面FPS帧率:如何采集FPS是要害,通过window对象注册onReportTimings回调,就能够失去整个构建和渲染过程的耗时,而后就能够算出页面的FPS。

页面加载时长(页面可见的工夫-页面创立的工夫):页面可见的工夫通过WidgetsBinding的addPostFrameCallback回调获取,页面创立的工夫通过页面初始化办法initState获取。

将以上数据上传到监控和性能剖析平台(mPaaS和烛龙),作为前期性能剖析和优化的参考数据,在开发过程中可通过DevToos性能剖析工具、Flutter Inspector剖析优化性能。按需加载,部分刷新也是罕用的优化伎俩。其它性能优化如布局加载优化、状态治理优化、启动优化-引擎预加载、内存优化、包大小优化等不再具体介绍。能够多关注Flutter社区,定期降级Flutter版本,会带来很好的播种。

4.2 如何优化ReactNative加载慢的问题?

一是能够预下载bundle包,缩小包加载的工夫,关上页面间接映射渲染,从而达到更快关上页面的目标,当然也能够预置包,须要均衡好包大小和性能;

二是尝试降级ReactNative最新版本,新版本升级了基础架构,次要包含线程模型,引入了异步渲染能力,优化JSBridge,对性能有显著晋升(作者征询过京东mPaaS团队,也在跟进中)。

4.3 如何优化APP中H5加载慢的问题

图7-加载H5流程介绍

图7形容了从WebView初始化到H5页面最终渲染的整个过程,以及和后面H5根本渲染流程进行剖析。耗时环节的次要有两点,一是WebView初始化,能够通过提前初始化WebView优化此问题;二是资源(html、js、css\图片等)的申请连贯和加载,能够用H5离线包计划解决此问题,通过资源的预加载,解决html、js、css和资源图片的加载问题,从而大大降低资源的加载工夫,晋升页面加载性能,甚至达到秒开的成果。

05总结

那么如何技术选型呢?应该以晋升开发效率和用户体验为前提去思考,而后再剖析关键因素:
1、技术栈的基础架构如何,原始架构是否优良,是否更面向未来倒退;
2、团队技术栈成熟度,学习的老本,社区的成熟度;
3、研发效率,实现代码多端复用,缩小多端差别,升高开发成本,更加专一于业务开发;而效率晋升是一个继续的收益过程,体现在业务倒退的整个生命周期。当然,对于新技术在实际后期会有一些老本,但相熟后总的收益是长期的;
4、是否更好解决多端一致性,更好解决UI设计师在UI审查时、测试同学在测试过程中、业务方在应用过程中发现的端与端并异问题,格调对立也是良好用户体验的重要体现;
5、反对动态化的水平,解决新需要必须发版的问题,也是业务的痛点,关键因素;
6、用户体验是最要害的,也需思考用户的应用环境(网络环境、手机配置)等;对于正式的C端我的项目,面对千万甚至亿级的用户量,技术选型策略肯定是在保障用户体验的根底上实现降本提效,用户第一,用户利益最大化即保障了公司的利益;对于非C端我的项目,可能须要思考在实现降本提效根底上晋升用户体验。

本文作者:京东国内技术研发部——卢旭、张公、姚峰、高鑫鹏、李澄锋、陈海蛟、高超、凡为连、单禹钦、慕新建