阿里的大佬们曾总结,「通常来讲,跨端技术有 4 类场景,分别是跨设备平台(跨Web
端和手机端)、跨操做系统(如跨Android
和iOS
)、跨App
以及跨渲染容器。」html
而其中移动端的跨平台技术一直以来都是很火热的话题,在如今都不看好客户端技术天花板的背景下,客户端的将来彷佛在逐渐朝着跨平台方向倾斜。前端
跨平台方案的优点十分明显,对于开发者而言,能够作到一次开发,多端复用,一套代码就可以运行在不一样设备上。这在很大程度上可以下降研发成本,同时可以在产品效能上作到快速验证和快速上线。web
可是,移动端的跨平台技术并非仅仅考虑一套代码可以运行在不一样场景便可,还须要解决性能、动态性、研发效率以及一致性的问题。编程
性能: 如何经过前端和客户端的结合,实现更优的渲染性能以及交互性能;小程序
动态性: 客户端怎样可以实现更低成本的发版、甚至不发版直接动态更新代码;
研发效率:如何提高不一样客户端的动态调试之类的研发效率;浏览器一致性: 如何实现一份代码的多端部署,并保证代码在多个客户端内展现形态的一致性以及兼容性问题。框架
现在,也已经出现了如WebView
、React Native
、Weex
、Flutter
、小程序等众多的移动端跨平台框架。可是行业内一致呈现出群雄争霸的形势,并无哪种框架能够真正上说能给完美解决以上的问题,同时博众人之所长,一超多强。异步
WebView
简单来讲就是用来展现HTML
的容器,用官方的话讲,叫作:布局
A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.
来给你们翻译一下:性能
用来显示网页的视图。 这是用来运行你本身的Web
浏览器或只再在应用中显示一些线上内容的基础。 它使用WebKit
渲染引擎显示网页,并包括在浏览历史中导航,放大和缩小以及执行文本搜索等方法。
因此简单来讲,WebView
就像是一个浏览器,可以在里面加载和渲染各类HTML
的页面。而同时,WebView
通常继承于原生客户端的UI
基类。因此,对于原生应用来讲,WebView
自己经过加载h5
页面、经过Chromium/WebKit
内核解析并进行UI
合成,生成客户端原生的UI
类,而后上屏展现。
而html
页面与native
的沟通交互则是经过所谓的JSB (JavaScript Bridge)
来实现的。客户端将原生系统级的接口进行封装,而后经过JSB
暴露给WebView
中前端页面进行调用。本质上这就是原生系统API
与前端页面Javascript
的通讯。
这样一来,前端开发者也能够很快地实现页面跨端,经过JSB
与原生系统进行沟通,保证跨端应用在总体上的能力打通和相互调用。
只不过,这样的机制劣势也很明显,就是前端页面与原生系统的通讯彻底取决于JSB
的构造,若是JSB
中缺乏调用原生能力的接口,那跨段能力也会直接受限。这种状况下依旧须要分别扩充原生应用中的JSB
接口,反而下降了开发效率。
此外,WebView
对UI
的渲染依赖于浏览器内核,而浏览器内核又独立于系统组件,因此没法保证跨端UI
的原生体验。原生体验永远是跨端技术追求的终极目标。
为了追求上面说过的原生体验的问题,Facebook
在2015年则推出了十分火热的React Native
,简称RN
。
RN
相较于WebView
,最大的区别就是再也不使用浏览器内核进行UI
渲染,而是使用一个叫作Virtual DOM
的东西来进行跨端UI
渲染的管理。
Virtual DOM
和DOM
实际上差很少,都是一个树形结构,在不一样节点上记录了UI的不一样元素。只不过Virtual DOM
将渲染工做是交给了原生渲染引擎,好比web
浏览器、iOS
、Android
,去处理。以后,不一样平台依旧是经过对应的Bridge
来建立不一样的Native
视图。
这样以来,体验有必定的提高。只不过React Native
和原生交互依赖的只有一个Bridge
,并且JS
和Native
交互是异步的,因此对须要和Native
大量实时交互的功能可能会有性能上的不足,好比动画效率,性能依旧是不如原生的。
Flutter
是谷歌内部孵化的移动端跨平台UI
框架,它是在RN
被饱受质疑的时候提出,算是目前最接近原生体验的框架。
从底层原理上来讲,它既没有采用WebView
与H5
混编的形式,也没有采用JavaScript
经过Bridge
进行桥接的模式,而是本身实现了一套UI
框架,直接在更底层进行UI
渲染。不只如此,它也再也不采用JavaScript
做为开发语言,而是选择了Dart
。称Dart
语言能够编译成原生代码,直接跟原生通讯。
之因此选择Dart
,其实Flutter
团队在早期就评估了十多种语言,并选择了Dart
,由于以为它符合他们构建用户界面的方式,而且还具备如下优点:
1Dart
是AOT (Ahead Of Time)
编译的,编译成快速、可预测的本地代码,使Flutter
几乎均可以使用Dart
编写。\
2Dart
也能够JIT(Just In Time)
编译,开发周期异常快,工做流颠覆常规(包括Flutter
流行的亚秒级有状态热重载);\
3Dart
能够更轻松地建立以60fps
运行的流畅动画和转场。Dart
能够在没有锁的状况下进行对象分配和垃圾回收。\
4Dart
使Flutter
不须要单独的声明式布局语言,如JSX
或XML
,或单独的可视化界面构建器,由于Dart
的声明式编程布局易于阅读和可视化。
Flutter
与上述Recat Native
、WebView
容器本质上都是不一样的,它没有使用WebView
、JavaScript
解释器或者系统平台自带的原生控件,而是有一套本身专属的Widget
,全部组件基于Skia
引擎自绘。
Flutter
因为是经过本身的引擎进行UI
渲染,所以在iOS
和Android
的效果基本一致。 相比之下,RN
是将UI
控件转换为对应平台的原生控件,因此不可避免的会存在必定差别。
从技术角度来看,RN实际上就是在Native
容器中提供了JavaScript
的运行环境,可是其布局引擎,渲染层都采用的是Native
的控件,所以UI
交互上仍然存在系统差别。而Flutter
方案更完全一些,连渲染层也换成了基于图形引擎自绘UI
控件,从而保证UI
交互的跨端一致性。