JSBridge通訊時間測試

asml發表於2018-11-14

寫在前面

每次想寫點東西,但總是覺得心中有千萬種騷操作,就是手跟不上大腦。別說了又要超鬼被舉報了。

JSBridge通訊時間測試

今天還是決定整理下最近的筆記了。先從JsBridge 通訊耗時測試開始吧。下面統稱JsB。

正文

之前hybrid專案中遇到過一個卡頓問題,現象是當JsB傳遞資料越大時頁面就越容易出現卡頓。一時間以為是原生部分 因,於是通過斷點發現,其實卡頓發生在原生接受到JsB訊息之前,也就是說是在H5部分或者JsB處理部分,由於自己前端剛入門,還特意去諮詢專案中的前端同事,可能是問題說的不清楚,最終估計是以為我在給他找問題,結果就直接說前端只有業務不會造成卡頓。 [圖片]

JSBridge通訊時間測試
所以讓我想起了那句話,Talk is cheap.show me the code.

JsB通訊的三個部分,先看看JSB訊息傳遞的呼叫順序。

Native 調 JS

JSBridge通訊時間測試
JS 調 Native
JSBridge通訊時間測試
圖片引用自 www.jianshu.com/p/fce3e2f9c… 上圖為安卓的呼叫順序。 iOS的其實也沒什麼差別,只是對應的原生介面名稱不一樣而。 WebviewJavaScriptBridge 原理圖.png
JSBridge通訊時間測試
圖畫的很醜,將就看吧。

加入埋點

從上圖看到各個部分的呼叫順序。所以,我們先看看JS調Native的耗時。

JS部分的時間

onclick() 到 JsB的doSend()方法,因為這部分都是JS程式碼,只要在onclick()時給window物件加一個屬性window.JSTime記錄觸發onclick()的瞬時間,然後再JsB的doSend()函式中當前時間減去window.JSTime就是JS部分的時間。 JsB部分時間

doSend()到原生接受到第一條訊息也就是觸發webview的- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler (本人用的WKWebview,如果是UIWebview自己找下回撥函式)

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (webView != _webView) { return; }
    NSURL *url = navigationAction.request.URL;
    __strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;

    if ([_base isWebViewJavascriptBridgeURL:url]) {
        if ([_base isBridgeLoadedURL:url]) {
            [_base injectJavascriptFile];
        } else if ([_base isQueueMessageURL:url]) {
            [self WKFlushMessageQueue];
        } else {
            [_base logUnkownMessage:url];
        }
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    
    if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {
        [_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
複製程式碼

但是我們檢視WebViewJavascriptBridge原始碼發現,在觸發原生回撥後,webview還是繼續調JsB的WebViewJavascriptBridge._fetchQueue()。所以JsB部分的時間,只需要在doSend()給window新增一個埋點window.JsBTime,然後在_fetchQueue()return的前面一行獲取瞬時時間減去window.JsBTime就是JsB的消耗時間啦。

原生部分

部分就忽略了,使用CFAbsoluteTimeGetCurrent() 做程式碼執行時間測試相對更加準確。

寫在最後

上面純屬個人見解,如果疏漏的地方,請指教。

JSBridge通訊時間測試

11.15 更新

demo地址

相關文章