今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

持續(xù)更新--請小伙伴關(guān)注! 喜歡的話給一個贊吧!

本文結(jié)尾有福利<窖纭!

1
移動跨平臺技術(shù)探究

◆ 為什么需要跨平臺?

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

◆ 跨平臺技術(shù)是如何發(fā)展起來的讨彼?

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

◆ 跨平臺技術(shù)選型有哪些?

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

◆ Flutter有什么獨特優(yōu)勢(為什么選擇Flutter)柿祈?

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

◆ 為什么說Flutter是高性能的哈误,體現(xiàn)在哪里哩至?

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

2

Flutter引擎原理剖析

先來看看Flutter的技術(shù)架構(gòu)圖:

C++引擎四個核心線程

Flutter 里四個核心線程:平臺線程、UI 線程蜜自、GPU 線程菩貌、IO 線程,它們的職責都是不一樣的:

★ 平臺線程(PlatformThread)對應(yīng)著安卓和 iOS 的主線程重荠。

★ UI線程(UI Thread)針對安卓本身的主線程菜谣,它就是一個獨立的線程。

★ GPU線程(GPU Thread)運行在 GPU 上的線程晚缩,它主要是處理 Skia 相關(guān)的任務(wù)尾膊。

★ IO線程(IO Thread)主要處理IO有關(guān)的任務(wù),比如:圖片編解碼等荞彼。

具體引擎架構(gòu)圖冈敛,如下圖示所示:

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

Flutter如何編譯成兩個平臺的應(yīng)用程序

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

首先看下面的引擎代碼是公共的部分,用于把程序的源代碼編譯Android和IOS兩個平臺的應(yīng)用程序鸣皂。中間左側(cè)綠色部分Flutter針對Android生成的一些文件抓谴,然后最終通過引擎會編譯生成Android的APK安裝包,中間右側(cè)藍色部分是Flutter針對IOS平臺生成的一些文件寞缝,然后最終通過引擎會編譯會生成IOS平臺的安裝包癌压。

線程通信(混合開發(fā)必須了解的難點)

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

這里以Android為例,對照Flutter做一個講解荆陆。Flutter里面的線程主要依賴于Dart里面的一些API滩届,比如我們常用的異步任務(wù)里面,需要用到:MicroTask和Future被啼,就是非常重要和關(guān)鍵的帜消。

我們可以看到技術(shù)是相通的,Android里面是一個Handler浓体,對應(yīng)一個Looper Thread泡挺,然后是一個MessageQueue,然后里面存放的是Message命浴。很巧妙的是Flutter也有類似的做法娄猫,F(xiàn)lutter有一個Looper線程,主線程復(fù)用了Native的生闲,然后為其他三個線程創(chuàng)建獨立的Looper媳溺。不過與Android不同的是:Flutter用的是兩個隊列,一個是微任務(wù)隊列(MicroTaskQueue)跪腹,一個是普通延遲任務(wù)隊列褂删。Flutter會先處理為任務(wù)隊列,再去處理普通任務(wù)隊列冲茸。類比Android來講屯阀,圖中的TaskRunner類似于Handler缅帘,PostTask就是把一個消息放到一個消息隊列的過程。和Android的Handler是很類似的难衰。所以在學(xué)新技術(shù)的時候钦无,舉一反三,懂得變通才能學(xué)的更好盖袭。

Dart虛擬機

同一個進程里可以有很多 Isolate失暂,兩個 Isolate 的堆是不能共享的。Dart開發(fā)團隊早就考慮到了交互的問題鳄虱,于是就設(shè)計了一個VM Isolate弟塞,它是一個用戶Isolate之間交互的橋梁,運行在 UI 線程中的拙已。我們可以把數(shù)據(jù)放在內(nèi)核態(tài)决记,因為這個內(nèi)核態(tài)可以共享數(shù)據(jù),然后把數(shù)據(jù)放到另一方的隊列中倍踪,另一方就可以拿到和使用這些數(shù)據(jù)了系宫。熟悉Android的朋友們應(yīng)該聽起來很熟悉,這就非常類似我們熟知的“進程間通信”建车。

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

可能這樣講還不是很清楚扩借,具體流程是什么樣的呢?請看下圖:

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

Isolate1是發(fā)送方缤至,創(chuàng)建一個SendPort 潮罪,Isolate2是接收方,創(chuàng)建一個ReceivePort凄杯。我們創(chuàng)建一個 Isolate的時候错洁,它里面有一個 worker 線程,worker 線程里面可以放入Task戒突。SendPort調(diào)用send方法,發(fā)送數(shù)據(jù)到PortMap里面描睦,這個里面每一個port對應(yīng)一個Isolate 的 MessageHandler,這個Handler包括兩個內(nèi)容:普通的消息隊列忱叭,一個是 OOB 高優(yōu)先級消息,數(shù)據(jù)放入隊列順序有優(yōu)先級區(qū)分韵丑。最后消息被封裝成一個 MessageTask,傳送到另一個Isolate里面去撵彻〉鲋辏回想一下是不是類似于Android的消息隊列?

Platform Channels

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

Flutter提供了Channel是用于和Native功能做交互轴合。Android這邊使用MethodChannel,IOS這邊使用FlutterMethdChannel受葛。最終Flutter通過銜接兩個平臺题涨,使用統(tǒng)一的規(guī)范去銜接兩個平臺,暴露出一些函數(shù)和接口总滩,然后就可以很容易的使用Flutter去調(diào)用Native的功能了。這個依賴于開發(fā)者的水平婉支,需要對Android或IOS比較了解才能更好的寫出插件出來澜建。pub.dev上面也有很多開源庫,不過往往開發(fā)中需求總是在變更的何之,開源庫遠遠達滿足不了實際開發(fā)需求的功能點,所以還是需要自己掌握Platform Channels的知識點比較好溶推。

3字節(jié)跳動在Flutter架構(gòu)上的實踐

下面來看字節(jié)跳動主要做了哪些架構(gòu)實踐奸攻,請看下圖:

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

從上圖中還是可以看到字節(jié)跳動做了很多基礎(chǔ)工作的睹耐,比如:容器化、混合工程硝训、渲染窖梁、包體積、編譯優(yōu)化纵刘、多端一體化等假哎∷膊叮看上去確實感覺是很多東西的山析。下面簡單的介紹其中比較關(guān)鍵的幾個:

容器化架構(gòu)

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

個人感覺所謂“容器化”,就類似于原生平臺的組件化或者業(yè)務(wù)分層架構(gòu)的思想秆剪。就是為普通業(yè)務(wù)打造可擴展的接口和行為準則爵政。不過這個Flutter容器化架構(gòu)要適應(yīng)Android和IOS兩個平臺,然后針對不同的平臺的業(yè)務(wù)行為需要定義統(tǒng)一的標準和規(guī)范以及封裝了一些通用業(yè)務(wù)模塊功能(其中的某些可以看做是基礎(chǔ)業(yè)務(wù)的基類)洁灵,比如:圖片調(diào)用掺出,直接去這里面的協(xié)議層,直接調(diào)用就可以了双抽,內(nèi)部都封裝好了闲礼,直接傳參調(diào)用,這里面有默認的適配柬泽,你也可以自定義锨并。有了“容器化”的架構(gòu),平臺基礎(chǔ)API的差異性就不需要考慮了琳疏,開發(fā)者只管調(diào)用內(nèi)部的功能模塊或者接口即可快速開發(fā)新需求功能空盼。

多端一體化實踐

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

這個就不用多說了新荤,就是寫一個應(yīng)用可以同時運行在Android、IOS篱瞎、Web上面,省去了大量的開發(fā)周期牵素,多端一體化結(jié)合了Flutter澄者,以及Flutter Web,然后定制化了一些內(nèi)部引擎和功能模塊的架構(gòu)赠幕,最終打造出了這套多端一體化的工程體系架構(gòu)询筏。

監(jiān)控體系

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

Flutter自帶的性能監(jiān)控工具顆粒度是很粗糙的,用的是物理平均逆屡,而不能反映真實的每一幀實時統(tǒng)計踱讨。UI線程和GPU線程的處理方式不一樣,這樣物理平均確實是不直觀的做法沫勿。

業(yè)界很多公司通用的做法是框架層去統(tǒng)計UI線程耗時時間味混,消息 post 到 UI,然后再post到GPU蔓挖。但是這種做法有兩個缺陷:一個是等待時間沒有考慮進去馆衔,一個是UI 線程非常快拷获,但是 GPU 線程非常慢减细,UI 線程向 GPU 線程跑消息時最多 Post 兩個消息,這時候 GPU 線程依然處理不過來驮吱,UI 線程就不會 Post 消息,但是 UI 線程體現(xiàn)不出來左冬。

字節(jié)跳動采用的是“高精度無侵入性能監(jiān)控方案”:引擎層提供了一套機制拇砰,可以知道繪制多少幀,統(tǒng)計你發(fā)了多少信號毕匀,統(tǒng)計 GPU 線程皂岔。另外“無侵入”體現(xiàn)在:框架系統(tǒng)會自動識別性能監(jiān)控滾動會在什么時候開始,什么時候結(jié)束躁垛。

Flutter Turbo

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

這個主要是性能提升的方案教馆,比如:消息調(diào)度、GC抑制胶滋、關(guān)閉Semantics悲敷、關(guān)閉抗鋸齒等,另外為了提高性能部宿,內(nèi)部有一個 Benchmark 跑分瓢湃,有了這些方案支持,可以大大的提升應(yīng)用程序額性能绵患。

圖片透傳優(yōu)化方案

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

我個人覺得這個方案還是挺不錯的落蝙,非常有借鑒價值作煌,值得學(xué)習和研究一下∽荩現(xiàn)有的方式 Image.network加載網(wǎng)絡(luò)圖片奏寨,傳入一個路徑就可以加載了病瞳,然后Dart底層引擎層做解碼操作。另外外接紋理方案也是不錯的套菜,也是可以實現(xiàn)的逗柴,但是它沒有在這個基礎(chǔ)上進行改造,性能上還有提升空間戏溺。字節(jié)跳動的透傳方案是這樣的:使用框架加載圖片旷祸,然后生成Bitmap,然后Native和Dart VM共享Bitmap托享,而不是直接的數(shù)據(jù)傳過來的闰围,然后Dart引擎再轉(zhuǎn)成Pixel buffer,這樣一來對性能有很大的提升辫诅。包體積優(yōu)化

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

大概有這些優(yōu)化:做了編譯優(yōu)化炕矮;對Flutter產(chǎn)物的數(shù)據(jù)端做了壓縮,對Skia做了裁剪档痪,不需要的東西刪掉了邢滑,引擎庫對一些功能三方庫也做了裁剪。

【雖說看的云里霧里乐纸,感覺還是很厲害的樣子。類型一萬個:“臥槽吗跋,這么牛逼宁昭!”】

今日頭條 字節(jié)跳動 Flutter架構(gòu)實踐

在這次會議上的第3個主題演講中,來自字節(jié)跳動的專家還專門對包體積優(yōu)化做了講解疆拘,我會在后面的文章再整理一下分享給大家寂曹。

啟動速度優(yōu)化

修改了引擎代碼,對啟動速度做了優(yōu)化芬失,幾乎提升了1倍匾灶。(雖然很牛逼,但是看不到摸不著颊糜,也不知道是如何修改的秃踩,我只能說希望早點貢獻給Flutter社區(qū),我們這些吃瓜群眾都來享一下福鸟赫,沾一點光啊消别。)

持續(xù)更新--請iOS的小伙伴關(guān)注! 喜歡的話給一個贊吧!

作為一個開發(fā)者岁经,有一個學(xué)習的氛圍跟一個交流圈子特別重要蛇券,這是一個我的iOS交流群:761407670 進群密碼“亮子”樊拓,不管你是小白還是大牛歡迎入駐 筋夏,分享BAT,阿里面試題苍糠、面試經(jīng)驗,討論技術(shù)岳瞭, 大家一起交流學(xué)習成長瞳筏!

提供:音視頻牡昆,逆向安防、Swift柱宦、算法播瞳、架構(gòu)設(shè)計、多線程忧侧,網(wǎng)絡(luò)進階牌芋,還有底層、Flutter等資料

摘自:字節(jié)跳動技術(shù)團隊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肯夏,一起剝皮案震驚了整個濱河市犀暑,隨后出現(xiàn)的幾起案子母怜,更是在濱河造成了極大的恐慌,老刑警劉巖碟贾,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異杀餐,居然都是意外死亡朱巨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門琼讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钻蹬,“玉大人凭需,你說我怎么就攤上這事×r冢” “怎么了枯怖?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長设捐。 經(jīng)常有香客問我塘淑,道長,這世上最難降的妖魔是什么槐沼? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任岗钩,我火速辦了婚禮肖油,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘视搏。我一直安慰自己,他們只是感情好佑力,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布筋遭。 她就那樣靜靜地躺著漓滔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪次和。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音畅形,去河邊找鬼诉探。 笑死肾胯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的敬肚。 我是一名探鬼主播艳馒,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼第美!你這毒婦竟也來了陆爽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤别威,失蹤者是張志新(化名)和其女友劉穎兔港,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衫樊,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡科侈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年臀栈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片权薯。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡盟蚣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阐枣,到底是詐尸還是另有隱情奄抽,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站第晰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏品抽。R本人自食惡果不足惜甜熔,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盆昙。 院中可真熱鬧,春花似錦秕磷、人聲如沸炼团。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锌俱。三九已至贸宏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吭练,已是汗流浹背线脚。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工叫榕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寓落。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓伶选,卻偏偏與公主長得像尖昏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子陨簇,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355