最近,有些朋友問我,到底GICXMLLayout
的性能如何?所以有了本篇文章。另外,考慮到如今Flutter
也比較火,爲了避免藏私,所以也加入對Flutter
的比較。所以這裏詳細的對三種開發方式進行橫向比較。前端
注1:
flutter
採用的是最新的1.0.0
版本。git
注2:
flutter
的測試都在profile
模式下測試,性能接近release
。github
文中用到的測試代碼能夠直接從這裏點擊下載緩存
在作比較以前,先肯定一個比較的樣例。這裏以以下UI內容爲例。bash
這裏面給出了一個顯示可變高度的列表的案例,這樣的案例比較具備通用性,有圖片的加載、有高度不固定文本的顯示、有高度不固定CellHeight的計算等等。下面針對這樣的案例,從各類角度來比較分析在不一樣的開發方式下的比較。架構
測試平臺是iPhoneX
,iOS 12.0
,由於作的是橫向比較,所以不在多設備上進行測試,只在iPhoneX
上進行測試分析。app
啓動時間的比較由兩個方面組成。iphone
main
以前
main
函數以前的時間表示的是iOS對動態連接庫的加載、系統加載等所耗時間。這個時間經過添加DYLD_PRINT_STATISTICS
宏來得到。函數
main
函數以後
main
函數以後的時間經過main
函數和applicationDidBecomeActive:
方法的時間差來得到。佈局
另外,爲了公平起見,測試方式採用的profile
的方式測試。
主要是考慮到
Flutter
在release
和debug
兩種模式下的性能差別太大,而release
和profile
兩種模式很接近,所以採用profile
的方式
另外,測試加載的數據爲11條,時間單位爲(秒)
main
函數以前的時間範例Total pre-main time: 205.82 milliseconds (100.0%)
dylib loading time: 191.47 milliseconds (93.0%)
rebase/binding time: 0.29 milliseconds (0.1%)
ObjC setup time: 6.29 milliseconds (3.0%)
initializer time: 7.76 milliseconds (3.7%)
slowest intializers :
libSystem.B.dylib : 4.67 milliseconds (2.2%)
複製代碼
main以前 | mian以後 | 總計 |
---|---|---|
0.201 | 0.099 | 0.3 |
0.206 | 0.086 | 0.292 |
0.210 | 0.092 | 0.302 |
0.197 | 0.089 | 0.286 |
0.195 | 0.098 | 0.293 |
平均 | 0.294 |
以上數據是原生APP的啓動時間,平均
0.294秒
main
函數以前的時間範例Total pre-main time: 342.71 milliseconds (100.0%)
dylib loading time: 291.83 milliseconds (85.1%)
rebase/binding time: 1.55 milliseconds (0.4%)
ObjC setup time: 15
.76 milliseconds (4.5%)
initializer time: 33.48 milliseconds (9.7%)
slowest intializers :
libSystem.B.dylib : 7.05 milliseconds (2.0%)
AsyncDisplayKit : 42.27 milliseconds (12.3%)
複製代碼
main以前 | mian以後 | 總計 |
---|---|---|
0.318 | 0.066 | 0.384 |
0.342 | 0.069 | 0.411 |
0.338 | 0.066 | 0.404 |
0.337 | 0.067 | 0.404 |
0.330 | 0.064 | 0.394 |
平均 | 0.399 |
main
函數以前的執行時間範例Total pre-main time: 206.08 milliseconds (100.0%)
dylib loading time: 189.66 milliseconds (92.0%)
rebase/binding time: 0.82 milliseconds (0.3%)
ObjC setup time: 7.52 milliseconds (3.6%)
initializer time: 8.06 milliseconds (3.9%)
slowest intializers :
libSystem.B.dylib : 4.61 milliseconds (2.2%)
複製代碼
main以前 | mian以後 | 總計 |
---|---|---|
0.218 | 0.115 | 0.333 |
0.203 | 0.105 | 0.308 |
0.209 | 0.113 | 0.322 |
0.211 | 0.110 | 0.321 |
0.203 | 0.107 | 0.310 |
平均 | 0.319 |
經過以上三種開發方式的數據分析能夠看出,
原生應用
,最長的是GIC
的應用。GIC
之因此最長,是由於在main
函數以前加載了太多的第三方庫,可是能夠看到main
函數以後的執行時間是最短的。flutter
在release
模式下的main
函數以前的加載時間跟原生應用能夠說相差無幾,從這裏能夠看出,大廠就是大廠,技術能力不得不服。flutter
在main
函數以後的執行時間是三種方式中是最長的。
flutter
的引擎、UI、GPU相關的操做都有專門的線程負責,區別於iOS
中的UI線程
。而flutter
在main
函數以後的執行時間倒是最長的,那麼說明,flutter
有些初始化操做多是在iOS的UI線程
中執行的。考慮到Flutter
app加載了一個Flutter.framework
,而且包含了對iOS
平臺調用的代碼(FlutterAppDelegate
、FlutterViewController
等),所以初步判斷是這個庫中的代碼的執行結果。
GIC
的main
以後執行時間最短應該說是情理之中,由於GIC
的列表佈局
、渲染
等都在非UI線程執行的(得益於Texture
)。也就是說,GIC
在UI線程上作的事情是在三種開發方式中最少的。從這裏也能夠看出,GIC
的問題在於對第三方庫的依賴太多,後續考慮如何減小對第三方庫的依賴,事實上目前已經在作對RAC
庫的剝離工做,相信剝離後會進一步的提高加載速度。
原生應用
在加載列表的時候採用的是最粗暴的方法,沒有任何的優化,沒有height緩存,沒有在後臺線程作height計算等等,所以原生應用在啓動時間方面也有進一步的優化空間。可是排名不會發生變化,最多就是mian
函數後的執行時間會縮短,但不會短過GIC
。
幀率
、CPU
、GPU
這三項數據的測試在iPhoneX上看不出明顯的不一樣,所以這裏就以iphone 6
的測試數據爲準。
測試方式:不停的滑動列表
在幀率方面,三種方式都差很少,基本上都能維持滿幀。
CPU佔用率從高到低排名爲:
flutter
(平均14%) > 原生(平均10%) >GIC
(平均7%)。
GPU佔用率從高到低排名爲:
flutter
(平均22%) > 原生(平均16%) >GIC
(平均12%)。跟CPU的結果差很少,flutter
在滑動的時候GPU耗費也高達22%,比最低的GIC
差很少高了一倍。
這一輪的測試中,flutter
基本上算是完敗了,不是百分之多少的差距,而是成倍的差距。
GIC
在UI層是基於Textrue
開發的,所以繼承了Textrue
的全部優勢。在這一輪測試中能夠說完勝。
測試方式:頁面加載完成後滑動列表,而後靜置一段時間 測試設備:iphone6
flutter
依然是以profile
模式測試。
由上面三張圖看出,flutter
(40MB)佔用的內存最多,GIC
(13.7MB)次之,原生
(9MB)應用佔用最少。
flutter
佔用了40MB,比原生應用多了將近3倍都不止。GIC
佔用了13.7MB
。
因爲
GIC
在基於Texuture
封裝的時候把佈局元素也做爲UI元素
封裝了,所以致使實際的內存佔用稍微高了點。
另外,GIC
在使用的過程當中建立了JSContext
,你能夠理解爲JS引擎。而在實際使用過程當中,JS並無佔用太多的內存。固然,這裏面涉及到JS功能也比較少,所以也沒法直接說JS佔用內存地。
爲了公平起見,這裏的測試基於release
模式下測試。另外,在打開和關閉bitcode
兩種模式下,包的大小差距會很大。這裏分別給出。
另外,測試應用已經踢除了靜態圖片資源。
bitcode
:1.1MBbitcode
:269KBbitcode
:16.2MBbitcode
:3.7MBflutter
自己就不支持bitcode。所以忽略bitcode。包的大小爲:11MB
經過上面的數據能夠分析出,在關閉bitcode的狀況下,包的大小依次爲,flutter
(11MB) > GIC
(3.7MB) > 原生(269KB)。
這裏以一個簡單的水平位移動畫做爲案例。
測試設備:iphone6使用CABasicAnimation
作動畫。
對於這麼簡單的動畫,都是滿幀運行的。所以只須要對GPU和CPU作分析比較便可。
原生
:
原生方式的性能表現是最好的。在動畫的時候,幾乎不佔用CPU資源。而GPU一直保持着7%的佔用。
GICXMLLayout
:
GIC
的GPU的佔用上跟原生的差很少,可是CPU卻一直有佔用,差很少維持着最高10%
的佔用。而且能夠注意到,CPU的佔用不是連續的而是斷斷續續的,這是有緣由的,由於GIC
的動畫是基於popAnimation
實現的,而popAnimation
是基於CADisplaylink
開發的,而且是按照60幀計算的。也就是差很少每秒60次的動畫計算。而只有在動畫計算的時候纔會佔用CPU資源,所以從測試結果來看,也是符合預期的。另外,在內存佔用方面,跟原生動畫差很少。
flutter
flutter
的動畫在GPU的佔用上幾乎是原生的兩倍以上。並且CPU也是連續維持着10%的佔用。而內存佔用方面也差很少是原生的兩倍以上。
在上面的測試中,因爲測試案例比較簡單,並不能表明大多數狀況,只是針對當前的測試案例得出的結果,僅僅只是給出一個參考。
對於原生引用的測試代碼可能有點不公平,沒有進行任何的優化。然而這並非關鍵,這樣正說明了原生應用的優化空間比較大。
原本還想作一個列表加載時間
測試的,可是對於flutter
卻無從下手,暫時不知道如何測試,等之後有方法了再作測試。
另外,這裏也不得不爲我本身的GICXMLLayout
作個宣傳。做爲一個獨立開發者維護的一個開源庫並不容易,我花了不少的心血在這上面。各位,若是以爲GIC
這個庫還能夠,還但願能給個star
,感謝!。項目地址
拋開原生應用不談,若是您想像前端開發同樣開發IOS應用,那麼我以爲GIC
值得您一試。無論從開發效率、上手難度、代碼可讀性等方面來講,GIC
都能有優秀的表現,而GIC
目前相較於flutter
等支持跨平臺的庫來講最大的缺點是不支持跨平臺。若是您開發的應用不考慮跨平臺開發的話,那麼GIC
是一個很好的選擇。
有的朋友可能會說,如今flutter很流行,而且
dart
的效率比JS
高。可是GIC
在UI
和業務邏輯(ViewModel)
上是兩套徹底不一樣的架構,UI
是純native的而且是基於Texuture
開發的,而ViewModel
你既可使用native
代碼來寫,也支持使用JS
來寫。另外在實際的應用(非遊戲)開發中,業務邏輯若是複雜到能經過不一樣的語言來區分的地步(好比dart和JS),那麼這樣的應用應該是一個很是複雜的應用了。所以我認爲在語言上來比較孰優孰慮並非最優先級。另外,事實上GIC
從架構設計上其實也能夠支持dart
語言、甚至其餘的腳本語言。