做爲盛行已久的開發方式,Hybrid的相關介紹已是至關廣泛了。不過看到博客園裏基本上都是從android或者ios的角度來說解的,對於h5的前端來講看起來只能是一直半解。感受有必要從前端的角度來理解和解讀一下Hybrid相關內容。做爲移動開發技術中不可或缺的一項,Hybrid 憑藉其特有的優點緊緊的佔據了一席之地。這裏就不展開討論討論Hybrid的優劣了(想了解請查看http://www.cnblogs.com/yexiaochai/p/4921635.html)javascript
html做爲一種解釋性語言,須要運行於解釋器之上。咱們經常使用的的pc端瀏覽器就是其一。做爲移動端的一種混合開發的模式,Hybrid是如何解決這一問題的呢。這就引出了webview這一律念。hybride中的h5依託於webview容器來(對應於ios和安卓,應該有不一樣實現,這裏就不是前端能夠細說的了)解釋運行。下面就看一下webview相關的部分。html
1、webview的概念:前端
先放一段基本定義:A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.
本身的理解:webview用來展現網頁的view組件,該組件是你運行本身的瀏覽器或者在你的線程中展現線上內容的基礎。使用webkit渲染引擎來展現,而且支持前進後退等基於瀏覽歷史,放大縮小,等更多功能。
簡單來講WebView是手機中內置了一款高性能 webkit 內核瀏覽器,在 SDK 中封裝的一個組件。不給過沒有提供地址欄和導航欄,只是單純的展現一個網頁界面。java
做爲hybrid中的webview,相比較於native中原生組件,給人最直觀的印象可能就是慢,不給過爲何這麼慢呢,固然影響因素是不少的,除去一些外部因素。與webview自身的初始化和加載過程也是分不開的 ,下面來看一下webview的初始化過程android
2、webview初始化ios
當App首次打開時,默認是並不初始化瀏覽器內核的;只有當建立WebView實例的時候,纔會建立WebView的基礎框架。因此與瀏覽器不一樣,App中打開WebView的第一步並非創建鏈接,而是啓動瀏覽器內核。web
在瀏覽器中,咱們輸入地址時(甚至在以前),瀏覽器就能夠開始加載頁面。json
在客戶端中,客戶端須要先花費時間初始化WebView完成後,纔開始加載。後端
而這段時間,因爲WebView還不存在,全部後續的過程是徹底阻塞的。簡單對比下兩個的渲染過程:設計模式
瀏覽器:
webview:
能夠看出在webview初始化以前,後面的步驟根本無從走起,耗時固然變長了。而且每次打開webview都要走這個過程。
3、Webview優化
從上面能夠看出來webview相對瀏覽器來講,影響點在於webview的初始化而且阻塞後面action的這個過程,其實說來也簡單(我只是說概念上,native的東西對我來講仍是很難的)對應問題的兩種表現形式,對應有兩個方向上的優化。
3.一、減小webview初始化的消耗:
鑑於每次打開都要進行初始化webview組件的這種場景,很天然的對應起來一種設計模式即單例模式,既然每次都要走相同步驟徹底能夠實例化一個全局對象,從而免去其餘過程的消耗。固然客戶端的同窗們也是這樣作的: 初始徹底能夠建一個全局,隱藏的webview。以供使用。省去了每次的初始化過程。
不過這樣的缺點也是有的,就看如何取捨了:
一、內存消耗:畢竟這貨一直存在
二、頁面間的跳轉:畢竟只有一個webview實例,每次不一樣的加載須要處理的狀況就比較多了。
3.二、針對阻塞的過程
每次的阻塞加載過程等待時間消耗也是很大的,就看能不能將串行的過程並行化。不過對於webview來講只能是這個樣子,不過咱們須要跳出僅僅侷限於webview的視線,webview僅僅是移動系統的一個組件,統計存在其餘組件,網絡請求的過程徹底能夠交給native來作,也正如native一直在作的同樣,徹底是能夠處理該過程的。例如後端同窗常常要開發的mapi,就是針對native的接口。
4、webview與native的交互
上面提到native能夠並行執行網絡請求,以加快webview的呈現時間。又一個問題出現了,webview如何調用native接口去請求數據並獲取native拿到的數據呢。除此以外還涉及到調用底層api等需求都須要藉助native實現,問題的核心就是二者的交互如何實現,做爲二者之間的溝通橋樑,jsbridge就應運而生了。
所謂交互無外乎兩大塊:一是h5調用native,另外一個是native調用h5。
1、Native調用JS:
原生調用h5比較簡單,能夠直接調用。畢竟這裏存在一個宿主的關係,脫離了webview,js就沒有生命力了,而native其餘功能是在webview外部的。因此反過來不能直接調用。
例若有以下代碼:
1 <script type="text/javascript"> 2 function myFunc() { 3 return "Text from web" 4 } 5 </script>
ios能夠直接經過webview的屬性調用(前端只能從方法名來看了,將js代碼當作字符串讀出來再解析)
NSString * result = [self.webView stringByEvaluatingJavaScriptFromString:@"myFunc()"];
2.H5網頁的JS調用Native
本質仍是用uiwebview的代理方法進行字段攔截(判斷url的scheme),實現js間接調用native的method。
android能夠直接給網頁中js函數注入一個原生代碼接口。
1 //至關於添加一個js回調接口能夠直接經過window全局對象調用對應接口了:
2 mWebView.addJavascriptInterface(this, "native"); 3 <button onClick="window.native.actionFromJs()">點擊調用Native代碼</button>
ios提及來也是注入只不過沒有android那麼方便。
在 webView 的 delegate 的 - (void)webViewDidFinishLoad:(UIWebView *)webView 裏用下邊的方式注入 JavaScript
1 NSString *js = @"(function() {\ 2 window.JSBridge = {};\ 3 window.JSBridge.callFunction = function(functionName, args){\ 4 var url = \"bridge-js://invoke?\";\ 5 var callInfo = {};\ 6 callInfo.functionname = functionName;\ 7 if (args)\ 8 {\ 9 callInfo.args = args;\ 10 }\ 11 url += JSON.stringify(callInfo);\ 12 var rootElm = document.documentElement;\ 13 var iFrame = document.createElement(\"IFRAME\");\ 14 iFrame.setAttribute(\"src\",url);\ 15 rootElm.appendChild(iFrame);\ 16 iFrame.parentNode.removeChild(iFrame);\ 17 };\ 18 return true;\ 19 })();"; 20 [webView stringByEvaluatingJavaScriptFromString:js];
之前端的角度來看這段代碼,是在 window 裏建立一個叫 JSBridge 的對象,而後在裏邊定義一個方法 callFunction,
這個方法的做用是把兩個參數打包爲 JSON 字符串,而後附帶到咱們自定義的 URL bridge-js://invoke? 後邊,
最後用 IFRAME 的方式來加載這個 URL當加載 IFRAME 的時候,就會調用 webView 的 delegate 的
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
(即特定方法來處理)方法。對url進行處理,把以約定字符開頭的url後面的json解析出來,執行對應方法。
至此webview與native的交互即jsbridge的實現從前端的角度也大概就是這樣子結束了,關於上面的客戶端代碼能夠自行研究,不給過前端來看也是不太難看懂。以上就是我對webview的理解了,歡迎你們相互交流共同進步。
參考文章:WebView性能、體驗分析與優化