Android原生、ReactNative、Flutter三者在設計上不同的理念
1.UI顯示流程
1.原生:通過layout布局決定UI效果,其中樣式文件和界面元素卸載不居中,更新的功能也在代碼中。
這種寫法 性能很高效,但是開發者使用起來很死板,通過文件的方式強行將代碼與布局分離。
2.RN:React獨創了Virtual DOM機制。Virtual DOM是一個存在于內存中的JavaScript對象,它與DOM是一一對應的關系,也就是說只要有Virtual DOM,我們就能渲染出DOM。當界面發生變化時,得益于高效的DOM Diff算法,我們能夠知道Virtual DOM的變化,從而高效的改動DOM,避免了重新繪制DOM,通過DOM映射成原生控件顯示在屏幕上。
React是一個專注于UI部分框架,做UI架構很厲害,性能相比原生會有些損耗,但是相對于html還是高出了很多。
3.Flutter: 基于dart描述的UI效果,直接通過SKia圖像處理引擎渲染到界面上。沒有虛擬DOM,也沒有原生映射,性能對于原生還會高一些。
性能高,而且可以熱重載,設計架構也是google出產,但是目前不穩定,支持的生態有效
2.狀態更新機制
1.原生:幾乎全靠開發者雙手完成狀態更新,比如TextView發生改變,需要findById然后setText,雖然目前有MVVM等非常優秀的設計模式,但這并不是一種完美的狀態機制,只不過讓你的狀態少了些。真正的狀態機制是指 數據狀態有周期,有傳遞特性,也能因為數據改變從而影響UI,在Android中是沒有這這種設計機制的。
2.RN:萬物皆組件,界面、按鈕、Text等都是組件,有組件就有狀態,有狀態就會發生相互傳遞,數據發生改變會實時影響UI。
3.Flutter: 所有組件分為兩類: 有狀態的和無狀態的。由于不是基于DOM展開,有狀態的組件性能開銷會大,因為需要底層進行實時監聽。其他的和RN的設計理念一樣,只是底層細節不一樣(Flutter的展示和繪制都是在NDK中實現的)
3.編譯流程
1.原生:Java文件編譯成Class,然后被dex工具編譯成dex,最終打包成APK文件,隨后通過adb命令安裝到手機中。如果Java文件發生變化,上述流程需要重新來一邊,再安裝到手機中,才能看到最終的效果。 原生不支持熱重載技術,最根本還是在于class的編譯機制與懶加載機制。
2.RN:.js文件通過adb推送到apk中,通過執行程序中的消息隊列,利用diff算法檢測到UI差異,通知DOM樹進行更新,重新渲染。通過相同的class加載不同的react文件,達到實時刷新界面的目的。
3.Flutter: .dart文件通過adb推送到apk中,通過Skia圖像處理引擎,引擎直接加載Dart描述的UI,然后重新渲染。
ReactNative 生命周期
getDefaultProps:在組件創建之前,會先調用getDefaultProps(),全局調用一次。
componentWillMount:準備加載組件,調用一次,這個函數調用時機是在組件創建并初始化了狀態之后,在第一次繪制render()之前,可以在這里做一些業務初始化操作。(相當于onMeasure)
componentDidMount: 這個函數調用的時候,其虛擬DOM已經構建完成,你可以在這個函數開始獲取其中的元素或者子組件了(相當于onLayout)
componentWillReceiveProps 接受父組件新的屬性(props)
shouldComponentUpdate 當組件接收到新的屬性和狀態改變的話,都會觸發這個函數
componentWillUpdate 如果組件狀態或者屬性改變,并且shouldComponentUpdate = true 會觸發這個函數