探索 messageHandler 的傳輸性能極限

本次測(cè)試的目標(biāo)是 iOS 8+ 之后提供的 WKWebview 提供的 JS 和 Native 通訊機(jī)制之 messageHandler宪赶,比較淺顯的探索下它各方面的極限。
測(cè)試 Demo

主要的測(cè)試場(chǎng)景包括

  1. messageHandler 可傳輸?shù)臄?shù)據(jù)類型有哪些痒玩?
  2. 以字符串為例淳附,messageHandler 最多可傳輸多少字節(jié)?
  3. 承接 2蠢古,在不同量級(jí)下的傳輸效果(是否丟失奴曙、速度等)如何?
  4. 如果是 native 向 WKWebview 傳輸數(shù)據(jù)便瑟,是否有類似的表現(xiàn)缆毁?
  5. 探索使用 messageHandler 的最佳方法。

測(cè)試方法

  1. 測(cè)試設(shè)備到涂,iPhone XR 模擬器脊框,Xcode 10.2
  2. 硬件,MacBook Pro (13-inch, 2016)践啄,Mem 16 GB 2133 MHz LPDDR3,3.1 GHz Intel Core i5
  3. 測(cè)試流程浇雹。啟動(dòng) App,將 Xcode 切換到 Debug Navigation屿讽,觀察內(nèi)存消耗昭灵;同時(shí)打開 Safari 開發(fā)者工具,切換到 Timing tab 里伐谈,觀察內(nèi)存的占用情況

測(cè)試用例

1. 傳輸數(shù)據(jù)類型

根據(jù) MDN 上對(duì) postMessage 描述烂完,

注意: 在 Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)之前, 參數(shù) message 必須是一個(gè)字符串诵棵。 從 Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)開始抠蚣,參數(shù) message被使用結(jié)構(gòu)化克隆算法進(jìn)行序列化。這意味著您可以將各種各樣的數(shù)據(jù)對(duì)象安全地傳遞到目標(biāo)窗口履澳,而不必自己序列化它們嘶窄。

Supported types (表1)

Object type Notes
All primitive types However, not symbols
Boolean object
String object
Date
RegExp The lastIndex field is not preserved.
Blob
File
FileList
ArrayBuffer
ArrayBufferView This basically means all typed arrays like Int32Array etc.
ImageData
Array
Object This just includes plain objects (e.g. from object literals, FormData objects)
Map
Set

按照上面的數(shù)據(jù),我嘗試了所有的數(shù)據(jù)類型距贷,包括 FormData柄冲。得出的結(jié)論和 AppleDocumentation 一致,

Allowed types are NSNumber, NSString, NSDate, NSArray, NSDictionary, and NSNull.

對(duì)于 JavaScript 側(cè)忠蝗,支持

Primitive Type, Boolean, String, Date, Array(包括 TypedArray)现横。

哪些不在 表1 中的數(shù)據(jù)類型,在調(diào)用 postMessage 即出錯(cuò),如postMessage(document)长赞;而哪些在表1中晦攒,但不在

Primitive Type, Boolean, String, Date, Array(包括 TypedArray)

中的數(shù)據(jù),傳到 native 時(shí)得哆,message.body 是個(gè)空對(duì)象 {};

對(duì)應(yīng) native 向 JS 傳輸數(shù)據(jù)的格式

只有一種,那就是字符串哟旗,凡是可以用字符串轉(zhuǎn)換的數(shù)據(jù)接口都可以借助字符串來實(shí)現(xiàn)打散贩据、傳輸、重建闸餐。

2. 傳輸數(shù)據(jù)速度饱亮。

我們以字符串為例,使用 for,字符串?dāng)?shù)組join等方式來模擬傳輸 1\10\100\1000 M數(shù)據(jù)試驗(yàn)舍沙。
(詳細(xì)的實(shí)現(xiàn)方式可以參考代碼近上,這種測(cè)試代碼準(zhǔn)確度不高,因?yàn)檠h(huán)和靜態(tài)字符串拂铡、臨時(shí)變量是否主動(dòng)銷毀等都會(huì)影響內(nèi)存占用壹无,所以這里得出來的數(shù)據(jù),在數(shù)據(jù)級(jí)和相對(duì)關(guān)系上可供參考)

下表是通過運(yùn)行我的 demo 跑了 3 次感帅,大概的數(shù)據(jù)統(tǒng)計(jì)斗锭。注意:webview 和 Xcode 里的內(nèi)存占用是獨(dú)立的。

表2失球, messageHandler 向 native 傳輸 數(shù)據(jù)

用例 webkit xcode 的內(nèi)存消耗 通訊耗時(shí) ms
1000M 352M/max, 180M 3.95G/max 141.M body.length = 1047552000, Costtime = 16323
100M 375M/max, 82M 259M/max 166.M body.length = 104755200, Costtime = 763
10M 102M/max ,73M 79.2M/max 57.M body.length = 10475520, Costtime = 79
1M 73.58/max ,73.58m 61.1/max 57.8M body.length = 1047552, Costtime = 12

352M/max, 180M 表示峰值是 252M岖是,之后維持在 180 M

表3, native 向 messageHandler 傳輸 數(shù)據(jù)

同時(shí)实苞,我還測(cè)試了 native 執(zhí)行 webview evaluateJavaScript 來傳數(shù)據(jù)的情況豺撑。

用例 webkit 瀏覽器 xcode 的內(nèi)存消耗 通訊耗時(shí) ms
1000M 3.98G/max 3.0G 3.98G/max 62.6.M total = 1047552000, CostTime = 15733
100M 350.51M/max 350.51M 261M/max 60.4.M total = 104755200, CostTime = 1307
10M 83.62M/max 83.33M 81.7.2M/max 60.9.M total = 10475520, CostTime = 129
1M 53.53/max 51.56m 62.1/max 59.7M total = 1047552, CostTime = 16

從表2、表3對(duì)比可見黔牵,對(duì)于 Xcode 而已聪轿,內(nèi)存占用是穩(wěn)定的,而對(duì)于 JS 端荧止,容易出現(xiàn)內(nèi)存泄漏屹电。從這點(diǎn)可見 iOS 的 ARC 的優(yōu)點(diǎn)。

3.可能有好奇的寶寶會(huì)追問跃巡,那到底到底有沒有最大值呢危号?

答:都沒有。

  1. h5 到 native 傳輸?shù)那闆r素邪,在我的測(cè)試用例中外莲,我用人肉和 2 分法(見代碼 index.html ),

[Log] 2149581562.5 is good, try hard. (index.html, line 67)
[Log] 2149581718.75 is good, try hard. (index.html, line 67)
[Log] 2149581796.875 is good, try hard. (index.html, line 67)
[Log] 2149581835.9375 is too much cost (index.html, line 64)
[Log] 2149581816.40625 is good, try hard. (index.html, line 67)
[Log] 2149581826.171875 is too much cost (index.html, line 64)
[Log] The choosed one is 2149581826.171875 (index.html, line 72)

測(cè)試出來 2G 是 messageHandler 傳輸?shù)臉O限。如果傳大于 2G的偷线,則會(huì)出現(xiàn) Out of Memory的錯(cuò)誤磨确。但我相信這是 JS 方法,

array.join('')

的極限声邦,如果是使用 File對(duì)象獲取的大于 2G 的文件我相信也是可以傳輸?shù)摹?/p>

  1. native 傳輸 h5情況乏奥,基本沒有限制,傳入 10000M 的時(shí)候亥曹,大概執(zhí)行了 5 分鐘邓了,內(nèi)存也飆到 11 G,但兩端都沒有出現(xiàn)問題媳瞪。


    傳 10000 M 時(shí)的內(nèi)存占用

理論上是無限的骗炉,現(xiàn)實(shí)是有限的,真正確定上限的是你的硬件蛇受,如我的電腦上執(zhí)行 10000 M 情況時(shí)句葵,已經(jīng)報(bào)警了,再超就會(huì)被殺進(jìn)程了兢仰。


內(nèi)存警告

5. 最佳參數(shù)

2 ~ 10 M乍丈,傳輸速度很快,可以傳 1M+ 的數(shù)據(jù)旨别,這時(shí)候的耗時(shí)也很小诗赌。對(duì)于 messageHandler 這么好的通道,還可以發(fā)掘的用途還很多秸弛,我想到的铭若,

  1. 可以將整個(gè)界面截圖(注意是滾動(dòng)截圖)獲得的數(shù)據(jù)傳到 native,讓 native 持久化递览。
  2. 保存整個(gè)渲染完畢的 html 結(jié)構(gòu)叼屠,這個(gè)功能可作為個(gè)性化的渲染結(jié)果,代替使用 phatom 這種無頭瀏覽器渲染獲得渲染結(jié)果的方式绞铃。

6. messageHandler 最多可以注冊(cè)多少個(gè)镜雨?

我相信是無數(shù)個(gè),因?yàn)闄C(jī)器配置有點(diǎn)差儿捧,就不再嘗試讓它包內(nèi)存警告了荚坞。window.webkit.messageHandlers 對(duì)象是延遲初始化,在內(nèi)存支持的情況下菲盾,會(huì)自然擴(kuò)展颓影。

結(jié)論

  1. native 調(diào)用 h5 傳數(shù)據(jù), JS 的入?yún)ⅲㄈ?Index.html 文件中的懒鉴,_content)诡挂,因?yàn)槭潜豢邕M(jìn)程持有碎浇,會(huì)造成泄漏,即使是即將 _content 置為 null璃俗,這個(gè)情況很嚴(yán)重奴璃,說明 webview evaluateJavaScript 的參數(shù)不能很長,不知如何化解這個(gè)問題城豁?


    內(nèi)部對(duì)象持有的
  2. 最佳參數(shù)是 2 ~ 10 M苟穆,所以如果大于 10 M 的數(shù)據(jù),可以考慮使用斷點(diǎn)續(xù)傳的方式钮蛛,這時(shí)候需要考慮網(wǎng)絡(luò)傳輸?shù)臋C(jī)制鞭缭,保證時(shí)效(ack_seq)正確和不丟失。

  3. 傳 100M 左右的數(shù)據(jù)很慢魏颓,會(huì)卡住主線程。我們的好朋友worker.js 這時(shí)候不能執(zhí)行 postMessage方法吱晒,也幫不了忙甸饱。但是可以在 worker.js 里做大數(shù)據(jù) slice 的工作。

  4. window.webkit.messageHandlers.postMessage 應(yīng)該是 window.postMessage 的封裝[ 從黑盒測(cè)試的角度來看仑濒,需要看源碼確認(rèn)]叹话。所以他可以很好的實(shí)現(xiàn) frame 和 iframe 之間的跨域問題。例如WebViewJavascriptBridge 因?yàn)樗昧?iframe 的_fetchQueue墩瞳,導(dǎo)致 WebViewJavascriptBridge在 iframe 是失效的驼壶。這也是 messageHandlers 的長處之一。

  5. messageHandler 傳不了 Blob 或者 FormData 等二進(jìn)制文件

參考

  1. Structured_clone_algorithm

  2. 理解DOMString喉酌、Document热凹、FormData、Blob泪电、File般妙、ArrayBuffer數(shù)據(jù)類型

  3. window.postMessage

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市相速,隨后出現(xiàn)的幾起案子碟渺,更是在濱河造成了極大的恐慌,老刑警劉巖突诬,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苫拍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡旺隙,警方通過查閱死者的電腦和手機(jī)绒极,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來催束,“玉大人集峦,你說我怎么就攤上這事。” “怎么了塔淤?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵摘昌,是天一觀的道長。 經(jīng)常有香客問我高蜂,道長聪黎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任备恤,我火速辦了婚禮稿饰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘露泊。我一直安慰自己喉镰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布惭笑。 她就那樣靜靜地躺著侣姆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沉噩。 梳的紋絲不亂的頭發(fā)上捺宗,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音川蒙,去河邊找鬼蚜厉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛畜眨,可吹牛的內(nèi)容都是我干的昼牛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼胶果,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼匾嘱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起早抠,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤霎烙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蕊连,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悬垃,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年甘苍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尝蠕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡载庭,死狀恐怖看彼,靈堂內(nèi)的尸體忽然破棺而出廊佩,到底是詐尸還是另有隱情,我是刑警寧澤靖榕,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布标锄,位于F島的核電站,受9級(jí)特大地震影響茁计,放射性物質(zhì)發(fā)生泄漏料皇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一星压、第九天 我趴在偏房一處隱蔽的房頂上張望践剂。 院中可真熱鬧,春花似錦娜膘、人聲如沸逊脯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽男窟。三九已至,卻和暖如春贾富,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牺六。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工颤枪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淑际。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓畏纲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親春缕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盗胀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)锄贼。 注意:講述HT...
    kismetajun閱讀 27,513評(píng)論 1 45
  • 前端開發(fā)面試題 <a name='preface'>前言</a> 只看問題點(diǎn)這里 看全部問題和答案點(diǎn)這里 本文由我...
    自you是敏感詞閱讀 763評(píng)論 0 3
  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級(jí)和職位的變化票灰,入門級(jí)到專家級(jí),廣度和深度都會(huì)有所增加宅荤。 題目類型: 理論知...
    怡寶丶閱讀 2,588評(píng)論 0 7
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,111評(píng)論 1 32
  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 9,737評(píng)論 0 44