[讀書筆記 Flutter 實戰 001] App 開發框架簡介


Posted by PGYW on 2021-04-19

相較於跨平台(Android與iOS)的開發工具,原生App開發框架易於調用手機功能,如:GPS、相機等而且速度快、效能高、可以實現複雜的動畫。但原生開發有個最致命的缺點:開發成本高,不同平台需要維護不同的程式,人力成本大。因此發展出一些開發框架。目前主流的跨平台開發的技術分成三大類:網頁 + 原生框架、JavaScript + 原生框架以及自繪 + 原生框架。以下將分別介紹三種技術分類。

跨平台框架技術

網頁 + 原生框架

這類的框架是透過原生框架的網頁瀏覽器元件,Andoird 的 WebView 或 iOS的WKWebView 來加載網頁。此類的 App 常被稱為 Web App 或是
Hybrid App。此類的開發框架的代表有 Cordova、Ionic。

技術難點

WebView/WKWebView 的核心就是網頁瀏覽器,在網頁中是無法調用系統功能API,例如 GPS、相機、藍牙等功能。通常搭配網頁進行開發的 Web App 皆會透過原生的開發框架來調用系統功能 API,再揭露給 WebView 以供 JavaScript 來調用,WebView/WKWebView 就成為 JavaScript 與系統功能 API 的溝通橋樑,兩者間傳遞的方式必須遵守標準的協議,該協議制定了通信的格式與內容。
將 WebView/WKWebView 作為 JavaScript 與原生框架之間通信的工具成為WebView JavaScript Bridge 簡稱為 JsBridge。

小結

Web App 的好處是使用網頁開發,開發資源龐大。再來就是當發生產品要更新的時候,網頁畫面可以隨時修改,不用再透過 Google play 與 Apple store 來發版更新。但最大的缺點就是效能不好、還有複雜的畫面與動畫 WebView 就不擅長了。

JavaScript + 原生框架

JavaScript + 原生渲染開發框架的代表有 React Native、Weex,而目前為止最著名的框架為React Native,是由 Facebook 所推出的開源 JavaSctipt 框架 React在 App 上的衍生項目。React 是一個專注於 UI(View)的 JavaScript 函式庫(Library)。

Flutter 的誕生受到 React Native 的啟發,為了未來能夠更快了解Flutter的原理,因此先介紹兩個重要的概念:Reactive Programming 與 DOM(Document Object Model)。接著再介紹React Native。

DOM(Document Object Model)

文件物件模型(Document Object Model, DOM)是 HTML、XML 和 SVG 文件的程式介面。它提供了一個文件(樹)的結構化表示法,並定義讓程式可以存取並改變文件架構、風格和內容的方法。DOM 提供了文件以擁有屬性與函式的節點與物件組成的結構化表示。節點也可以附加事件處理程序,一旦觸發事件就會執行處理程序。 本質上,它將網頁與腳本或程式語言連結在一起。

Reactive Programming

React 提出『狀態改變UI隨之自動改變』,響應使用者改變的事件而執行畫面重構的工作,即稱為 Reactive Programming,其原理如下:
React 收到使用者改變狀態的通知,首先根據目前的畫面,再結合最新狀態改變畫面,計算出目需要變化的部分,只更新需要更新的部分,避免整個畫面都重畫進而,提高效能。
狀態改變後,React 不會立即計算並更新畫面的變化,相反的是,React 會先在當前的狀態下建立由 JavaScript 模擬的抽象層,稱為 Virtual DOM,當使用者做出狀態改變,都會自動地同步到 Virtual DOM,等完成所有動作之後再一次同步到真實的 DOM 中,並且只把差異的部分處理後輸出到頁面的 DOM 上,這種運算法叫做 DOM diff。為何不每次都直接操作 DOM 呢?前端運算中成本最高的就是 DOM 的操作,因此降低 DOM 的操作是必要的。

React Native

React Native 是React 主要的區別在 Virtual DOM?React 中 Virtual DOM 最終會映射為瀏覽器 DOM,而 React Native 中Virtual DOM会通過JavaScriptCore 映射為原生的物件。
JavaScriptCore 是 JavaScript 與原生框架通信的橋樑,作用和JsBridge依樣。在iOS中,很多 JsBridge 的實現都是基於 JavaScriptCore。
React Native 將 Virtual DOM 映射為原生的物件過程:首先,佈局事件的傳遞,再來將 DOM 的佈局傳遞給原生框架,原生框架藉此生成原生的物件。
透過這樣的方式,React Native 透過 JavaScript 來呼叫原生物件來渲染畫面,效能會比 Web App 來得好。於此同時,也只需要維護一份程式碼。

//原文有提到 Weex 與 快应用,有興趣可以查看看。

小結

JavaScript + 原生渲染的好處是使用網頁開發,開發資源龐大,只需要維護一份程式碼。
雖然在畫面渲染的效能比Web App來得好,但還是要透過 JavaScript 來呼叫原生物件來渲染畫面,使有溝通成本的,有些狀態如拖移畫面,可能會因為 JavaScript 頻繁的通信而造成卡頓的狀況。另外,JavaScript 為腳本語言,執行時需要JIT(Just In Time),效率和AOT(Ahead Of Time)的程式還是有差的。
另外由於畫面依賴原生物件,不同平台的物件需要單獨維護,就拿每年必更新的iOS為例,互叫的方式可能會突然改變,有些物件甚至會直接被移除,而用到的 JavaScript 套件不一定會立馬跟上,這時就會變得很棘手。此外,有時候很多物件會受到原生UI系統的限制,如 Android 中手勢衝突消期的規則是固定的,有可能分別使用不同人寫的套件,而導致手術衝突,遇到這樣的問題也是相當麻煩的。

自繪 + 原生框架

透過在不同平台統一渲染的方式來繪製UI,而不依賴原生物件,可以做到不同平台,UI一致。相對於上述兩種技術,在繪製UI的效能上將大幅提升,甚至接近原生框架的效能。但為了確保UI的繪製效能,通常都會採用 AOT 編譯,不能像 Web App 或 JavaScript 的框架那樣動態編譯,因此開發效率相對較低。如 QT 這樣的跨平台C++ 圖形介面開發框架,每次畫面修改後,都需要重新編譯後才能看到畫面的更新,編譯的速度會隨著專案的增加也隨之增加,真的很花時間。另外,C++ 需要開發者一行管理記憶體,並沒有 JavaScript中的 GC 機制,學習成本相對較高。

QT For Mobile 的社群相對上述的技術都來得少,生態系其實不健全,通常來說開發 App並不會考慮採用 QT。

Flutter

Flutter 為 Google 發佈的跨平台框架,與 QT 相同,不使用原生的物件,實作了自己的繪圖引擎,使用自身的佈局與繪製系統。然而,Flutter 的社群能量與 QT 卻截然不同,身為 Google 的親孩子,經過赫赫有名的 軟體界大佬 Google 大力推廣,目前已經有非常龐大的技術社群,很多問題都能夠查閱,不害怕問題無法獲得解答。
在開發上,Flutter 支援 Hot Reload,這是一個能夠動態的重載畫面的超級功能,在 iOS 與 Android 的模擬器上可以一秒內重載畫面,真的是福音!開發過原生框架,一定會遇到需要重新編譯才能確認畫面效果,而需要耗費多少時間在編譯與查看畫面的等待時間上,而 Hot Reload 則大幅度的改善了這個問題。
Hot Reload 是 Fluter 所使用的 Dart 語言支援 JIT 運行模式才有的功能,另外,在 Release 適用 Dart AOT 模式編譯的。

小結

該技術的優點在繪製UI的效能上將大幅提升,甚至接近原生框架的效能。而缺點是編譯的速度也與原生框架相同,相當花時間。但 Flutter 有 Hot Reload 功能,卻不用擔心這個問題。
綜觀下來,Flutter 無庸置疑是一個直得投資的開發框架!

總結

將上述三種框架做個比較:

技術 UI渲染方式 效能 開發效率 框架代表
網頁 + 原生框架 瀏覽器渲染 一般 Cordova、Ionic
JavaScript + 原生框架 原生物件渲染 React Native、Weex
自繪 + 原生框架 使用系統API渲染 Flutter高, QT低 QT、Flutter

《Flutter实战》电子书 - 第一章:起步 - 1.1 移动开发技术简介


#Flutter #APP #iOS #Android







Related Posts

淺談 AJAX、JSONP 和 CORS

淺談 AJAX、JSONP 和 CORS

[Release Notes] 20201116_v1 - Add Email login

[Release Notes] 20201116_v1 - Add Email login

[Release Notes] 20200924_v1 - Fix blog post serie checkbox bug & add publish type modal

[Release Notes] 20200924_v1 - Fix blog post serie checkbox bug & add publish type modal


Comments