导读

本文首要针对常用跨端技能Flutter、ReactNative、Weex、H5,从技能特色、根本架构、编译原理、根本烘托流程等进行整理剖析;以及一些常见功能问题怎么优化处理,然后怎么进行技能选型或在进行事务开发时挑选不同技能栈的逻辑是什么。

01 背景

随着技能的开展,产生了越来越多的端,如Android、iOS、Mac、Windows、Web、Fuchsia OS、鸿蒙等,而随着公司事务的开展,出现了越来越多的事务场景;作为APP开发人员,在日常工作中难免会碰到以下问题,如:1、UI设计师在进行UI检查时、测验同学在回归测验进程中、事务方在运用进程中,多少会发现端与端存在着差异,影响用户体会;2、相同的事务、相同的功能在不同的端上,需求每端投入资源去开发完结。而移动互联网的开展已经处于晚期,领导们越来越关心投入产出。

与此同时,出现了一些跨端的技能处理计划,能够完结一套代码在多端运转,处理事务开展上的痛点,如Flutter、ReactNative、Weex、H5(注:小程序和其它根据DSL的计划暂不在本文讨论规模)。然后对一些常用APP进行了比照剖析,定论和预期共同,大部分都在运用跨端技能;Flutter和ReactNative运用率较高,Weex运用率相对低一些,H5根本都在运用,运用多种跨端技能结构是一种常态。那么,它们都有哪些特色呢?

02 四种技能栈特色介绍

APP常用跨端技术栈深入分析 | 京东云技术团队

图1-技能栈特色

经过图1,从功能、开发言语、烘托、包巨细、社区、支撑渠道等方面整理了它们的首要特色;不由产生几个问题:为什么原生和Flutter功能更好?为什么ReactNative和Weex功能相对较差?为什么H5页加载慢?这些功能问题该怎么去优化,这是需求深化了解的问题,下面将从根本的架构、烘托流程、编译运转原理等一同剖析。

03根底架构介绍

3.1 Flutter根底架构介绍

APP常用跨端技术栈深入分析 | 京东云技术团队

图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根底架构介绍

APP常用跨端技术栈深入分析 | 京东云技术团队

图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根底架构介绍

APP常用跨端技术栈深入分析 | 京东云技术团队

图4-Weex根底架构

Weex是阿里2016年发布的跨端结构,如图4所示,Weex编译产品js bundle能够部署在服务端,APP加载完即可运转,也能够看出具备动态发布的才能;和ReactNative相似,Weex在实际运转进程中,js侧会构成一个dom,并经过Bridge交由原生侧解析,映射到原生控件再由原生才能进行烘托;Weex根据JS V8引擎,根据Vue设计,支撑Android、iOS、Web三端。

3.4 WebView根底架构介绍

APP常用跨端技术栈深入分析 | 京东云技术团队

图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 根本烘托流程比照

APP常用跨端技术栈深入分析 | 京东云技术团队

图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加载慢的问题

APP常用跨端技术栈深入分析 | 京东云技术团队

图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端项目,可能需求考虑在完结降本提效根底上提高用户体会。

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

来历:京东云开发者社区,转载请注明来历