阿里的大佬們曾總結,「通常來講,跨端技術有 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
交互的跨端一致性。