前言
你们好,我是
simbawu ,
@BooheeFE Team Leader,关于这篇文章,有问题欢迎来
这里讨论。
随着移动互联网的普及和快速发展,手机成了互联网行业最大的流量分发入口。以及随着5G的快速发展,将来愈来愈多的“端”也会如雨后春笋般快速兴起。而“快”做为互联网的生存之道,为了占领市场,企业也会积极跟进,快速布局。同一个应用,各个“端”独立开发,不只开发周期长,并且人员成本高。同时,做为技术人员,也不该该知足于这种重复、低能的工做状态。在这样的形势下,跨平台的技术方案也受到愈来愈多人和企业的关注。接下来,我将从原理、优缺点等方面为你们分享《跨平台技术演进》。javascript
H5
说到跨平台,没人不知道H5。不论是在Mac、Windows、Linux、iOS、Android仍是其余平台,只要给一个浏览器,连“月球”上它都能跑。css
浏览器架构
下面,咱们来看看让H5如此横行霸道的浏览器的架构:前端

- User Interface 用户界面:提供用户与浏览器交互
- Browser Engine 浏览器引擎:控制渲染引擎与JS解释器
- Rendering Engine 渲染引擎:负责页面渲染
- JavaScript Interpreter JS解释器:执行JS代码,输出结果给渲染引擎
- Networking 网络工做组:处理网络请求
- UI Backend UI后端:绘制窗口小部件
- Data Storage 数据存储:管理用户数据
浏览器由以上7个部分组成,而“渲染引擎”是性能优化的重中之重,一块儿了解其中的渲染原理。java
渲染引擎原理
不一样的浏览器内核不一样,渲染过程会不太同样,但主要流程仍是一致的。android

分为下面6步骤:ios
- HTML解析出DOM Tree
- CSS解析出CSSOM
- DOM Tree与CSSOM关联生成Render Tree
- Layout 根据Render Tree计算每一个节点的尺寸、位置
- Painting 根据计算好的信息绘制整个页面的像素信息
- Composite 将多个复合图层发送给GPU,GPU会将各层合成,而后显示在屏幕上。
从以上6步,咱们能够总结渲染优化的要点:git
- Layout在浏览器渲染过程当中比较耗时,应尽量避免重排的产生
- 复合图层占用内存比重很是高,可采用减少复合图层进行优化
以上就是浏览器端的内容。但H5做为跨平台技术的载体,是如何与不一样平台的App进行交互的呢?这时候JSBridge就该出场了。github
JSBridge原理
JSBridge,顾名思义,是JS和Native之间的桥梁,用来进行JS和Native之间的通讯。web

通讯分为如下两个维度:小程序
那么App内加载H5的过程是什么样的呢?
App打开H5过程

打开H5分为4个阶段:
- 交互无反馈
- 打开页面 白屏
- 请求API,处于loading状态
- 出现数据,正常展示
这四步,对应的过程如上图因此,咱们能够针对性的作性能优化。
优缺点分析
下面,咱们进行H5的优缺点分析:
优势
- 跨平台:只要有浏览器,任何平台均可以访问
- 开发成本低:生态成熟,学习成本低,调试方便
- 迭代速度快:无需审核,及时响应,用户可毫无感知使用最新版
缺点
- 性能问题:在反应速度、流畅度、动画方面远不及原生
- 功能问题:对摄像头、陀螺仪、麦克风等硬件支持较差
虽然H5目前还存在不足,但随着PWA、WebAssembly等技术的进步,相信H5在将来可以获得越来也好的发展。
小程序
2018年是微信小程序飞速发展的一年,19年,各大厂商快速跟进,已经有了很大的影响力。下面,咱们以微信小程序为例,分析小程序的技术架构。

小程序跟H5同样,也是基于Webview实现。但它包含View视图层、App Service逻辑层两部分,分别独立运行在各自的WebView线程中。
View
能够理解为h5的页面,提供UI渲染。由WAWebview.js来提供底层的功能,具体以下:
- 消息通讯封装为WeixinJSBridge
- 日志组件Reporter封装
- wx api(UI相关)
- 小程序组件实现和注册
- VirtualDOM,Diff和Render UI实现
- 页面事件触发
每一个窗口都有一个独立的WebView进程,所以微信限制不能打开超过5个层级的页面来保障用户体验。
App Service
提供逻辑处理、数据请求、接口调用。由WAService.js来提供底层的功能,具体以下:
- 日志组件Reporter封装
- wx api
- App,Page,getApp,getCurrentPages等全局方法
- AMD模块规范的实现
运行环境:
- iOS:JavaScriptCore
- Andriod:X5内核,基于Mobile Chrome 53/57
- DevTool:nwjs Chrome 内核
仅有一个WebView进程
View & App Service通讯
视图层和逻辑层经过系统层的JSBridage进行通讯,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层将触发的事件通知到逻辑层进行业务处理。
优缺点分析
优势
- 预加载WebView,准备新页面渲染
- View层和逻辑层分离,经过数据驱动,不直接操做DOM
- 使用Virtual DOM,进行局部更新
- 组件化开发
缺点
- 仍使用WebView渲染,并不是原生渲染,体验不佳
- 不能运行在非微信环境内
- 没有window、document对象,不能使用基于浏览器的JS库
- 不能灵活操做 DOM,没法实现较为复杂的效果
- 页面大小、打开页面数量都受到限制
既然WebView性能不佳,那有没有更好的方案呢?下面咱们看看React Native。
React Native

RN的理念是在不一样平台上编写基于React的代码,实现Learn once, write anywhere。
Virtual DOM在内存中,能够经过不一样的渲染引擎生成不一样平台下的UI,JS和Native之间经过Bridge通讯
React Native 工做原理

在 React 框架中,JSX 源码经过 React 框架最终渲染到了浏览器的真实 DOM 中,而在 React Native 框架中,JSX 源码经过 React Native 框架编译后,与Native原生的UI组件进行映射,用原生代替DOM元素来渲染,在UI渲染上很是接近Native App。
### React Native 与Native平台通讯

- React Native用JavaScriptCore做为JS的解析引擎,在Android上,须要应用本身附带JavaScriptCore,iOS上JavaScriptCore属于系统的一部分,不须要应用附带。
- 用Bridge将JS和原生Native Code链接起来。Native和 JavaScript 两端都保存了一份配置表,里面标记了全部Native暴露给 JavaScript 的模块和方法。交互经过传递 ModuleId、MethodId 和 Arguments 进行。
优缺点分析
优势
- 垮平台开发:相比原生的ios 和 android app各自维护一套业务逻辑大同小异的代码,React Native 只须要同一套javascript 代码就能够运行于ios 和 android 两个平台,在开发、测试和维护的成本上要低不少。
- 快速编译:相比Xcode中原生代码须要较长时间的编译,React Native 采用热加载的即时编译方式,使得App UI的开发体验获得改善,几乎作到了和网页开发同样随时更改,随时可见的效果。
- 快速发布:React Native 能够经过 JSBundle 即时更新 App。相比原来冗长的审核和上传过程,发布和测试新功能的效率大幅提升。
- 渲染和布局更高效:React Native摆脱了WebView的交互和性能问题,同时能够直接套用网页开发中的css布局机制。脱了 autolayout 和 frame 布局中繁琐的数学计算,更加直接简便。
缺点
- 动画性能差:React Native 在动画效率和性能的支持还存在一些问题,性能上不如原生Api。
- 不能彻底屏蔽原平生台:就目前的React Native 官方文档中能够发现仍有部分组件和API都区分了Android 和 IOS 版本,即使是共享组件,也会有平台独享的函数。也就是说仍不能真正实现严格意义上的“一套代码,多平台使用”。另外,由于仍对ios 和android的原生细节有所依赖,因此须要开发者若不了解原平生台,可能会遇到一些坑。
- 生态不完善:缺少不少基本控件,第三方开源质量参差不齐
展望将来
虽然RN还存在不足,但RN新版本已经作了以下改进,而且RN团队也在积极准备大版本重构,可否成为开发者们所信赖的跨平台方案,让咱们拭目以待。
- 改变线程模式。UI 更新再也不同时须要在三个不一样的线程上触发执行,而是能够在任意线程上同步调用 JavaScript 进行优先更新,同时将低优先级工做推出主线程,以便保持对 UI 的响应。
- 引入异步渲染能力。容许多个渲染并简化异步数据处理。
- 简化 JSBridge,让它更快、更轻量。
既然React Native在渲染方面还摆脱不了原生,那有没有一种方案是直接操控GPU,自制引擎渲染呢,咱们终于迎来了Flutter!
Flutter
Flutter是Google开发的一套全新的跨平台、开源UI框架,支持iOS、Android系统开发,而且是将来新操做系统Fuchsia的默认开发套件。渲染引擎依靠跨平台的Skia图形库来实现,依赖系统的只有图形绘制相关的接口,能够在最大程度上保证不一样平台、不一样设备的体验一致性,逻辑处理使用支持AOT的Dart语言,执行效率也比JavaScript高得多。
Flutter架构原理

Dart优点
不少人会好奇,为何Flutter要用Dart,而不是用JavaScript开发,这里列下Dart的优点
- Dart 的性能更好。Dart在 JIT模式下,速度与 JavaScript基本持平。可是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。速度的提高对高帧率下的视图数据计算颇有帮助。
- Native Binding。在 Android上,v8的 Native Binding能够很好地实现,可是 iOS上的 JavaScriptCore不能够,因此若是使用 JavaScript,Flutter 基础框架的代码模式就很难统一了。而 Dart的 Native Binding能够很好地经过 Dart Lib实现。
- Fuchsia OS。Fuchsia OS内置的应用浏览器就是使用 Dart语言做为 App的开发语言。
优缺点分析
优势
- 性能强大:在两个平台上重写了各自的UIKit,对接到平台底层,减小UI层的多层转换,UI性能能够比肩原生
- 优秀的语言特性:参考上面Dart优点分析
- 路由设计优秀:Flutter的路由传值很是方便,push一个路由,会返回一个Future对象(也就是Promise对象),使用await或者.then就能够在目标路由pop,回到当前页面时收到返回值。
缺点
- 优势即缺点,Dart 语言的生态小,精通成本比较高
- UI控件API设计不佳
- 与原生融合障碍不少,不利于渐进式升级
总结
移动互联网的普及和快速发展,跨平台技术风起云涌,这也是技术发展过程当中的必经之路,等浪潮退去,才知道谁在裸泳。我我的更看好H5或类H5方案,给它一个浏览器,连“月球”都能跑,这才是真正的跨平台,其余都是浮云。
广而告之
本文发布于薄荷前端周刊,欢迎Watch & Star ★,转载请注明出处。
欢迎讨论,点个赞再走吧 。◕‿◕。 ~