最近一段時間 Flutter 的技術熱度很是高,常常在逛 Github 的時候瞄到,出現的多了,也就引發了個人興趣;而後來看看這是個什麼玩意。前端
稍微搜一下大概能知道:web
Flutter 是 Google 一個新的用於構建跨平臺的手機 App 的 SDK,同時也將是 Google Fuchsia 下開發應用的主要工具。編程
它在 2017 年發佈初始版本,很明顯是一個爲了解決不一樣平臺 App 重複開發的問題,這也不是什麼新技術,相似的還有 React Native、Weex。canvas
簡單說就是達到 「write once, run everywhere」 的目的,怎麼這麼耳熟呢。。。小程序
深刻了解能夠看一下這篇:爲何說 Flutter 是革命性的後端
Dart
Flutter 使用 Dart 語言開發,Dart 能夠被編譯(AOT)成不一樣平臺的本地代碼,讓 Flutter 能夠直接和平臺通信而不須要一箇中間的橋接過程,從而提升了性能。微信小程序
這裏,有必要提一下 React Native,也是一種流行的跨平臺構建方案,是 Facebook 在 2015 年左右搞出來的,要比 Google 早的多。瀏覽器
Facebook 最明智的一點就是讓 RN 採用 JS 做爲開發語言。由於 JS 擁有很是好的羣衆基礎和較低的學習門檻,因此 RN 不只能夠吸引大量的前端開發者加入,並且能夠和 React 社區造成正向互補,進一步鞏固 Facebook 在前端領域的統治力。基本上全部合格的前端開發者均可以低成本的學習並使用 RN 進行跨端開發。微信
Google 讓 Flutter 採用 Dart 進行開發,多是基於對將來的判斷,但願 Dart 能夠逐步取代 JS 成爲前端的開發標準。實際上 Dart 的語法更接近原生開發語言,用 Java 或者 Swift 的開發者會更加喜歡。架構
RN 採用了橋接系統服務,順帶將系統 UI 也橋接到了 JaveScript 中,可經過原生 UI 系統進行渲染,效率方面確定比 Flutter 差一點,可是成熟度與方便程度與新發展的 Flutter 根本不是一個量級,不事後續怎樣咱們繼續看吧。
跨平臺方案的發展
WebView
第一個跨平臺的框架基於 JavaScript 和 WebView,例如 PhoneGap, Apache Cordova, Ionic 等,在蘋果發佈 iOS 以前,他們鼓勵第三方開發者爲 iPhone 構建網頁應用程序,所以使用 Web 技術構建跨平臺應用程序是瓜熟蒂落的一步。
我感受這跟咱們以前說的用 HTML5 響應式佈局寫差很少,既能夠簡單打包成 App,又可讓手機直接在瀏覽器中訪問,不過像 JavaScript 這樣的語言很難直接與本地代碼(例如服務)進行通訊,所以他們會經過一個在 JavaScript 代碼和原生代碼的「橋樑」進行上下文切換,由於平臺服務一般不會常常被調用,因此這並不會致使太大的性能問題。
React Native
響應式視圖火起來後,他們經過使用從響應式編程中借用的編程模式來簡化 Web 視圖的建立過程。2015 年, React Native 將響應式視圖的許多優點帶給了移動應用程序。
由於 JavaScript 時常會訪問原生 UI 組件,因此它也必須通過這些「橋接器」,界面上的 UI 控件一般被頻繁地訪問(在動畫、轉化或者用戶用手指「滑動」屏幕上的某些東西時,每秒被訪問高達 60 次),所以這極可能會致使性能問題。
這是理解 React Native 性能的其中一個關鍵,JS 代碼和原生代碼自己都是很快的,瓶頸常常發生在當咱們視圖從一邊轉向另外一邊時。 將來構建高質量的應用程序時,咱們必須將使用橋接的次數控制到最小。
橋接器是 RN 的核心,相比 WebView 它不光橋接了系統服務,還把 UI 順便也橋接了過去,這樣寫出來的 UI 最終也會被渲染爲原生控件,這也讓它在混合開發的時候變得容易。
對於 JS 開發者來講, 畫 UI 只須要畫到 Virtual DOM 中,不須要特別關心具體的平臺, 仍是原來的單線程開發,仍是原來 HTML 組裝 UI(JSX),仍是原來的樣式模型(部分兼容 )。
不過 UI 的渲染是比較頻繁的,想要不卡頓還必需要 60FPS+,這對性能是個不小的挑戰。
由於 RN 是採用 JS 開發,還須要一個 JS 的環境,不過這個不用太操心,想多瞭解下 RN,能夠看一下:React Native運行原理解析
Flutter
和 React Native 同樣,Flutter 也提供響應式的視圖,Flutter 採用不一樣的方法避免由 JavaScript 橋接器引發的性能問題,即用名爲 Dart 的程序語言來編譯。
Dart 是用預編譯的方式編譯多個平臺的原生代碼,這容許 Flutter 直接與平臺通訊,而不須要經過執行上下文切換的 JavaScript 橋接器。編譯爲原生代碼也能夠加快應用程序的啓動時間。
實際上,Flutter 是惟一提供響應式視圖而不須要 JavaScript 橋接器的移動 SDK,這就足以讓 Fluttter 變得有趣而值得一試,但 Flutter 還有一些革命性的東西,例如它是如何實現 UI 組件的。
組件(Widgets)
這應該是最重要的一塊東西,咱們能夠輕鬆的用 Web 技術模擬出原生的界面或者符合預期的界面與動畫,可是讓他們擁有原生組件的特性與流暢度或者事件綁定是比較難的,比較這些模擬的組件最終仍是外來物,再說性能方面也是一個問題。
Flutter 的系統架構包含大量賞心悅目、快速、可定製、可擴展的 Widgets。沒錯,Flutter 不須要使用系統 UI 組件(或 DOM WebViews),它自帶了 Widgets。
Flutter 將 UI 組件和渲染器從平臺移動到應用程序中,這使得它們能夠自定義和可擴展。Flutter 惟一要求系統提供的是 canvas,以便定製的 UI 組件能夠出如今設備的屏幕上,以及訪問事件(觸摸,定時器等)和服務(位置、相機等)。
Dart 程序和執行數據編碼與解碼的原平生臺代碼之間仍然有一個接口(參考上圖中的藍綠色部分),但這能比 JavaScript 橋接器快幾個數量級。
Flutter 最大的改進之一就是它的佈局,它大大簡化了佈局的「規則」,例如咱們都用過的 CSS3 定義了 375 個屬性,規則能夠相互影響甚至發生衝突,要處理他們之間的關係很是複雜,然而咱們經常使用的一些規則佔比很是小,因此 Flutter 改變了傳統的佈局方式。
體驗過 Flutter 的基本都能感受到界面是很是順滑的。
虛擬DOM
現有的響應式 web 視圖庫都引入了虛擬 DOM,DOM 表明 HTML 的文檔對象模型,虛擬 DOM 則表明 JS 利用 DOM API 抽象出來的版本。
在響應式 Web 視圖(由 ReactJS 和其餘系統實現)中,虛擬 DOM 是不可變的,每次更改,全部的東西都得重建。系統將虛擬 DOM 與真正的 DOM 進行比較,生成一組最小的更改,而後執行這些更改,以更新真正的 DOM。最後,平臺從新繪製真實的 DOM 到畫布中。
這聽起來增長了不少額外的工做,但它是值得的,由於操縱 HTML DOM 是很是耗費系統資源的。
React Native 也作相似的工做,可是是在移動應用程序當中進行的。它會操控移動平臺上的原生組件而不是 DOM。它構建一個 UI 組件的虛擬樹,與原生組件進行比較,並只更新已更改的部件。
結語
其實不管 RN 仍是 Flutter 都有至關大的野心實現全平臺制霸。除了 Android、iOS 平臺以外,RN 已經能夠經過第三方工具支持 Windows UMP、Web、Desktop、macOS,甚至近期京東開源的 Alita 項目已經實現 RN 到微信小程序的打通。
RN 當下仍是最成熟的一個解決方案,畢竟已經發展的多年,資料也比較多,即便這樣官方 Github 也有很多的 issue 未處理,更不要說新興的 Flutter,不過從長遠看,Flutter 也必將是一場革命吧。
最後我想說,JS NB!,加上 Node、Vue、React、Element 的加持,還有什麼不能寫,前端、後端、桌面 GUI、App 通吃,不知道明天又會被玩出什麼花樣來。