iOS:原生應用 VS Flutter VS GICXMLLayout 比較

最近,有些朋友問我,到底GICXMLLayout的性能如何?所以有了本篇文章。另外,考慮到如今Flutter也比較火,爲了避免藏私,所以也加入對Flutter的比較。所以這裏詳細的對三種開發方式進行橫向比較。前端

注1:flutter採用的是最新的1.0.0版本。git

注2:flutter的測試都在profile模式下測試,性能接近releasegithub

文中用到的測試代碼能夠直接從這裏點擊下載緩存

在作比較以前,先肯定一個比較的樣例。這裏以以下UI內容爲例。bash

這裏面給出了一個顯示可變高度的列表的案例,這樣的案例比較具備通用性,有圖片的加載、有高度不固定文本的顯示、有高度不固定CellHeight的計算等等。下面針對這樣的案例,從各類角度來比較分析在不一樣的開發方式下的比較。架構

1. 啓動時間

測試平臺是iPhoneX,iOS 12.0,由於作的是橫向比較,所以不在多設備上進行測試,只在iPhoneX上進行測試分析。app

啓動時間的比較由兩個方面組成。iphone

  1. main以前

    main函數以前的時間表示的是iOS對動態連接庫的加載、系統加載等所耗時間。這個時間經過添加DYLD_PRINT_STATISTICS宏來得到。函數

  2. main函數以後

    main函數以後的時間經過main函數和applicationDidBecomeActive:方法的時間差來得到。佈局

另外,爲了公平起見,測試方式採用的profile的方式測試。

主要是考慮到Flutterreleasedebug兩種模式下的性能差別太大,而releaseprofile兩種模式很接近,所以採用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秒

GICXMLLayout

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

Flutter

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

分析

經過以上三種開發方式的數據分析能夠看出,

  1. 啓動時間最短的是原生應用,最長的是GIC的應用。
  2. GIC之因此最長,是由於在main函數以前加載了太多的第三方庫,可是能夠看到main函數以後的執行時間是最短的。
  3. flutterrelease模式下的main函數以前的加載時間跟原生應用能夠說相差無幾,從這裏能夠看出,大廠就是大廠,技術能力不得不服。
  4. fluttermain函數以後的執行時間是三種方式中是最長的。

    flutter的引擎、UI、GPU相關的操做都有專門的線程負責,區別於iOS中的UI線程。而fluttermain函數以後的執行時間倒是最長的,那麼說明,flutter有些初始化操做多是在iOS的UI線程中執行的。考慮到Flutterapp加載了一個Flutter.framework,而且包含了對iOS平臺調用的代碼(FlutterAppDelegateFlutterViewController等),所以初步判斷是這個庫中的代碼的執行結果。

  5. GICmain以後執行時間最短應該說是情理之中,由於GIC的列表佈局渲染等都在非UI線程執行的(得益於Texture)。也就是說,GIC在UI線程上作的事情是在三種開發方式中最少的。

從這裏也能夠看出,GIC的問題在於對第三方庫的依賴太多,後續考慮如何減小對第三方庫的依賴,事實上目前已經在作對RAC庫的剝離工做,相信剝離後會進一步的提高加載速度。

原生應用在加載列表的時候採用的是最粗暴的方法,沒有任何的優化,沒有height緩存,沒有在後臺線程作height計算等等,所以原生應用在啓動時間方面也有進一步的優化空間。可是排名不會發生變化,最多就是mian函數後的執行時間會縮短,但不會短過GIC

2. 幀率CPUGPU

這三項數據的測試在iPhoneX上看不出明顯的不一樣,所以這裏就以iphone 6的測試數據爲準。

測試方式:不停的滑動列表

原生

GICXMLLayout

flutter

分析

  1. 幀率:

    在幀率方面,三種方式都差很少,基本上都能維持滿幀。

  2. CPU:

    CPU佔用率從高到低排名爲:flutter(平均14%) > 原生(平均10%) > GIC(平均7%)。

  3. GPU:

    GPU佔用率從高到低排名爲:flutter(平均22%) > 原生(平均16%) > GIC(平均12%)。跟CPU的結果差很少,flutter在滑動的時候GPU耗費也高達22%,比最低的GIC差很少高了一倍。

這一輪的測試中,flutter基本上算是完敗了,不是百分之多少的差距,而是成倍的差距。

GIC在UI層是基於Textrue開發的,所以繼承了Textrue的全部優勢。在這一輪測試中能夠說完勝。

3. 內存佔用

測試方式:頁面加載完成後滑動列表,而後靜置一段時間 測試設備:iphone6

原生

GICXMLLayout

flutter

flutter依然是以profile模式測試。

分析

由上面三張圖看出,flutter(40MB)佔用的內存最多,GIC(13.7MB)次之,原生(9MB)應用佔用最少。

  1. 能夠看出flutter佔用了40MB,比原生應用多了將近3倍都不止。
  2. GIC佔用了13.7MB

    因爲GIC在基於Texuture封裝的時候把佈局元素也做爲UI元素封裝了,所以致使實際的內存佔用稍微高了點。

另外,GIC在使用的過程當中建立了JSContext,你能夠理解爲JS引擎。而在實際使用過程當中,JS並無佔用太多的內存。固然,這裏面涉及到JS功能也比較少,所以也沒法直接說JS佔用內存地。

4. 包大小。

爲了公平起見,這裏的測試基於release模式下測試。另外,在打開和關閉bitcode兩種模式下,包的大小差距會很大。這裏分別給出。

另外,測試應用已經踢除了靜態圖片資源。

原生

  1. 打開bitcode:1.1MB
  2. 關閉bitcode:269KB

GICXMLLayout

  1. 打開bitcode:16.2MB
  2. 關閉bitcode:3.7MB

flutter

flutter自己就不支持bitcode。所以忽略bitcode。包的大小爲:11MB

分析

經過上面的數據能夠分析出,在關閉bitcode的狀況下,包的大小依次爲,flutter(11MB) > GIC(3.7MB) > 原生(269KB)。

5. 動畫

這裏以一個簡單的水平位移動畫做爲案例。

測試設備:iphone6

原生

使用CABasicAnimation作動畫。

GICXMLLayout

flutter

分析

對於這麼簡單的動畫,都是滿幀運行的。所以只須要對GPU和CPU作分析比較便可。

  1. 原生:

    原生方式的性能表現是最好的。在動畫的時候,幾乎不佔用CPU資源。而GPU一直保持着7%的佔用。

  2. GICXMLLayout:

    GIC的GPU的佔用上跟原生的差很少,可是CPU卻一直有佔用,差很少維持着最高10%的佔用。而且能夠注意到,CPU的佔用不是連續的而是斷斷續續的,這是有緣由的,由於GIC的動畫是基於popAnimation實現的,而popAnimation是基於CADisplaylink開發的,而且是按照60幀計算的。也就是差很少每秒60次的動畫計算。而只有在動畫計算的時候纔會佔用CPU資源,所以從測試結果來看,也是符合預期的。另外,在內存佔用方面,跟原生動畫差很少。

  3. flutter

    flutter的動畫在GPU的佔用上幾乎是原生的兩倍以上。並且CPU也是連續維持着10%的佔用。而內存佔用方面也差很少是原生的兩倍以上。

總結

在上面的測試中,因爲測試案例比較簡單,並不能表明大多數狀況,只是針對當前的測試案例得出的結果,僅僅只是給出一個參考。

對於原生引用的測試代碼可能有點不公平,沒有進行任何的優化。然而這並非關鍵,這樣正說明了原生應用的優化空間比較大。

原本還想作一個列表加載時間測試的,可是對於flutter卻無從下手,暫時不知道如何測試,等之後有方法了再作測試。

另外,這裏也不得不爲我本身的GICXMLLayout作個宣傳。做爲一個獨立開發者維護的一個開源庫並不容易,我花了不少的心血在這上面。各位,若是以爲GIC這個庫還能夠,還但願能給個star,感謝!項目地址

拋開原生應用不談,若是您想像前端開發同樣開發IOS應用,那麼我以爲GIC值得您一試。無論從開發效率、上手難度、代碼可讀性等方面來講,GIC都能有優秀的表現,而GIC目前相較於flutter等支持跨平臺的庫來講最大的缺點是不支持跨平臺。若是您開發的應用不考慮跨平臺開發的話,那麼GIC是一個很好的選擇。

有的朋友可能會說,如今flutter很流行,而且dart的效率比JS高。可是GICUI業務邏輯(ViewModel)上是兩套徹底不一樣的架構,UI是純native的而且是基於Texuture開發的,而ViewModel你既可使用native代碼來寫,也支持使用JS來寫。另外在實際的應用(非遊戲)開發中,業務邏輯若是複雜到能經過不一樣的語言來區分的地步(好比dart和JS),那麼這樣的應用應該是一個很是複雜的應用了。所以我認爲在語言上來比較孰優孰慮並非最優先級。另外,事實上GIC從架構設計上其實也能夠支持dart語言、甚至其餘的腳本語言。

相關文章
相關標籤/搜索