PonyCui 發表於 2019.05.12編程
自移動平臺(iOS / Android)誕生以來,跨平臺開發的嘗試從未中止,成功與失敗並存。而 Flutter 的出現並不是偶然,是 Google 基於前人長期以來探索的道路,輔以大規模人力、物力創造獲得的。小程序
在真正開始 Flutter Talk 以前,我以爲有必要讓你們知道,十多年來前輩們是如何走出這條血路的。瀏覽器
在初代 iPhone 發佈之時,也就是 iOS 1 的年代,WebKit 技術是全球開發者最爲尊崇的跨平臺技術之一。同時,Apple 也致力於推進 WebKit 走向商業化、跨平臺化。你可能不知道的是,在 iOS 6 以前,iOS 應用的渲染引擎就是基於 WebKit,iOS 應用實質上也是一個 WebApp。自那時開始,Chrome、Safari 份額日漸上升,WebKit 功不可沒。框架
然而,WebKit 終究只是一個瀏覽器渲染引擎,跨平臺方案要求的不只是通用的渲染方案,其背後的語言層、圖形層以及基礎環境層都佔據很是重要的位置。可是,恰恰就是這些重要的底層組件,各家瀏覽器開發商都有不一樣的實現方案,通俗來說,就是不兼容。編程語言
以 WebKit 爲基礎的跨平臺方案,終於走向各自爲政的道路。iOS 6 之後,WebKit 成爲了配角。Android 自此至終沒有將 WebKit 置於正室位置。工具
假如 WebKit 不能成爲原生組件的惟一渲染引擎,那麼,可否取而代之使用 WebView 做爲替代方案?畢竟 WebView 的使用已經有二十多載的歷史了,網頁的編寫也相對簡單,各類瀏覽器廠商也廣泛遵循 w3c 和 ecma 規範。性能
可是,使用 WebView 做爲跨平臺方案有一個重大的弊端 —— 沒法調用原生能力。例如,WebView 要調起原生系統的相機、膠捲,就很是困難。動畫
爲了彌補這一缺陷,有了 PhoneGap、 JavascriptBridge 這些方案。然而,Patch 終究只是打補丁,這種小修小補的集合體,最終只能讓『跨平臺』成爲一個替補演員的角色。同時,WebView 又是一個黑盒子,一旦出現未知問題,只能乾着急。ui
Facebook 的主應用在最初的版本就是使用 WebView 進行開發的,然而,在後續的版本中,又徹底使用原生重構整個應用了,具體緣由?編碼
React Native 是 Facebook 於 2016 年公佈開源的 Hybrid 開發引擎,其核心思想是但願在 ReactJS 的基礎上,封裝一套 Native 渲染的混合開發框架。React Native 仍然是基於 JavaScript 的跨平臺方案,與 WebView 不同的是,渲染層由原生實現。其優勢在於,RN 能充分使用原生組件能力,從而減小無謂的組件開發工做。
然而,React Native 有一個致命的缺點 —— 慢!這種慢很大程度是由於 JavaScript 的單線程模型形成的,RN 的跨平臺能力,很大程度依賴於 JavaScript 的統一實現,RN 將全部的觸摸事件、動畫驅動以及頁面棧都封裝在 JS 內,經過一致的 JS 實現以求達到跨平臺一致性。這是一個極大的矛盾,一方面,咱們不該該將過於繁重的工做交給 JavaScript 實現,而一方面,過多的平臺代碼會使得平臺一致性的特性減弱。
更要命的是,RN JS 線程與原生 UI 線程並不處於同一線程,線程間通訊徹底依賴以 JSON 爲主的序列化、反序列化方式進行。當使用 RN 構建大規模應用時,性能問題更顯突出。
小程序並非嚴格意義上的跨平臺開發框架,鑑於小程序產品的成功,仍然有必要在這裏討論一下。小程序實質上仍然是 WebView,沒錯,是 WebView。小程序的核心是敲掉 WebView 的 JS 環境,使開發者沒法直接操縱 WebView 中的對象。緊接着,提供一個徹底受控的 JavaScript 環境,經過該環境控制多個 WebView 的 DOM 渲染並響應 DOM 事件。
小程序能夠很好地運行在受控應用中,但在性能、交互、功能要求更高的場景中,並沒有太大優點。筆者認爲,小程序是一個好產品,但不是一個好方案。
那麼,Flutter 呢?Flutter 比上面所說的各類方案更優秀嗎?在論證 Flutter 是否更優秀前,筆者以爲應該先讓你們知道 Flutter 背後的原理。
Flutter 的原理很簡單,建立一張畫布,並在這張畫布上渲染界面。同時,監聽原生事件,在 Dart 層響應全部觸摸事件。這和跨平臺遊戲引擎的原理是一致的。抽象出統一的界面、觸摸、交互語言,而後使用一致的渲染引擎呈現最終產物。
簡單的原理背後,總有複雜的實現支撐!
Dart 是 Google 開發的相似 Java 的一門編程語言,是 Flutter 的基礎運行環境,它支持編譯至 JS / AOT / JIT 多種 Target。 在 AOT Target 下,其執行效率與原生編譯型語言幾乎一致!在 JIT Target 下,又兼有熱更新、熱重載的便利性,使得應用 Restart 更輕鬆。同時,Dart 能夠編譯至 JS,使得 Flutter Web 成爲可能。
Dart 能夠說是精簡版的 Java,若是你有相關的 Java 編碼經驗,應該很容易上手。
Skia 是 Google 開發的 2D 渲染引擎,是 Flutter 的底層渲染環境,它支持在不一樣平臺上運行,包括 iOS / macOS / Windows / Android / Linux 等,Skia 同時是 Chrome 的渲染引擎。
藉助 Skia,Flutter 得以在不一樣平臺上有極爲一致的輸出表現。
在 Skia 與 Dart 之上,是 Flutter UIToolbox,UIToolbox 是基於 Dart 開發的一套全新的界面方案。爲什麼 Flutter 須要一套全新的界面方案?還記得原理中說起到,Flutter 是在一塊獨立的畫布上渲染的嗎,正因如此,Flutter 沒法複用 iOS / Android 原生的 UI 組件,必須自行實現一套。
在這背後,是龐大的工做量!
Flutter 完整的實現 Material 和 Cupertino 兩套組件庫,Material 團隊還告知 Flutter 團隊,Flutter 是 Material 的最佳還原。
Flutter 團隊也意識到,編碼工具的易用性對於開發者來講,很是重要!所以,Flutter 團隊花費了大量精力改進 VSCode 和 Android Studio 的插件表現。今天,你能快速地開始、構建 Flutter 應用,背後負載着 Flutter 工程師無數多個日夜的努力,在此爲他們點贊。
那麼,將全部的基礎混合在一塊兒,效果如何?
在性能上,能與原生應用並肩嗎?
答案是,能!並且,可能更好!筆者藉助 Flutter 開發了一個完整的應用,從應用的幀率表現來看,Flutter 能在大部分狀況下達到 >= 50 FPS 的效果。
同時,Flutter 也很好的避免了 RN 所遇到的困境,Flutter 的主線程就是 UI 線程,它能夠在主線程處理 UI 的更新,也能夠在主線程處理觸摸的響應而無須通過複雜的線程間通訊。
再者,Flutter 也借鑑了 React 以數據驅動界面的思想,在應用開發的過程當中,極大地提高了開發效率。
Flutter 的面世離不開前輩們的努力,同時,也是基於 Google 在語言、渲染等基礎庫上大量的投入下產生的。如此跨時代的跨平臺開發框架,值得各位去嘗試一下。