在JSBridge實現後,前端網頁與原生的交互已經通了,接下來就要開始規劃API,明確須要提供哪一些功能來供前端調用。html
可是在這以前,還有一點重要工做須要作:前端
明確H5與Native的職責劃分,肯定哪一些功能能夠由H5實現,哪一些功能只能由原生實現react
使用Hybrid模式,用H5開發頁面的本質是:git
減小工做量(一套代碼,多個平臺),以及快速的更新迭代(譬如線上更新),並且還須要考慮Native端的高性能以及系統API調用能力(不然直接用純H5就能夠了)github
所以在進行職責劃分時,就得充分的考慮前端渲染,JS語言以及原生渲染,Java/OC等語言的特性,__基本總結以下:__web
嘗試過,也對比過不少的混合開發框架,譬如Dcloud的HTML5+,釘釘裏的DD API,本身也嘗試過不一樣的方式,
最終發現導航欄的最好作法仍是由原生提供,核心緣由以下:ajax
僅基於這一點,就已經拍板了由Native導航欄組件+webview(加載H5)來組成頁面,而原生提供一些API來供網頁操控導航欄(譬如標題,按鈕等)canvas
總體頁面佈局以下:segmentfault
而H5端能夠經過原生提供的API來操控導航欄,如下舉例爲quick中規劃的API:react-native
// 僅提供一部分示例 quick.navigator.setTitle({ title: '標題', subTitle: '子標題', success: function(result) {}, error: function(error) {} }); quick.navigator.setRightBtn({ isShow: 1, text: '按鈕右1', // 設置圖片的優先級會較高 //imageUrl: 'http://xxx/test.png', // 從右數起第幾個 which: 0, success: function(result) { /** * 按鈕點擊後回調 */ }, error: function(error) {} });
實際開發中Native導航欄組件+webview也就知足絕大部分的頁面需求了,可是還有一些特殊頁面是這種實現達不到的,譬如多Tab頁面
上述這種內含多tab的頁面,每個tab裏都是單獨的頁面,並且能夠經過滑動等手勢來切換,甚至tab還會有一些漸變更畫,導航欄也配合改變等(常見於APP首頁)
爲了統一實現,這類頁面的導航欄與底部tab均是由原生實現,由H5經過API打開這類原生頁面,並將須要加載的網頁地址傳入,以下
quick.page.openLocal({ className: '那種原生頁面的標識,能夠惟一查詢到相應的界面', data: { // 須要加載的n個url url1: 'http://...', urln: 'http://...', }, success: function(result) {}, error: function(error) {} });
而後,在每個前端頁面(webview里加載的內容),能夠分別在對於頁面的腳本里進行本身的交互控制
對於一些重要的業務頁面,如登錄,註冊,支付等,處於安全性以及交互性的考慮(就是一個APP的門面),會採用徹底由Native實現
(固然了,通常這些頁面的變更頻率也不大)
webview加載網頁時,通常狀況原生都是會對加載狀況進行監聽的,好比是否網絡異常。服務器響應異常,頁面加載崩潰等,
爲了防止APP假死,原生會提升一些默認提示頁面
上述只是一個原型示例,實際上,不少狀況均可以由原生提供統一提示頁面,
如404,頁面崩潰,網絡錯誤等
除了關鍵性頁面,還有一類,就是H5很差實現的(或者說達不到要求的、實現代價過大的),也應該由原生實現
譬如以某圖像處理軟件某個界面截圖爲例
這種頁面涉及到了明顯不太適合H5實現的圖像處理,所以原生纔是更佳的選擇(固然了,實際上H5的canvas是由圖像處理能力的)
前面提到了頁面的選擇,但頁面內的內容也是須要抉擇的,好比一些UI顯示控件(alert,toast等)
雖然H5完成能夠實現這些UI控件,而且能夠和原生模擬的同樣,可是基於如下考慮,全部系統級的UI所有由原生實現並提供API:(原生和H5需統一風格)
通常狀況下H5經過以下API便可調用
quick.ui.toast('xxxx'); quick.ui.alert('xxxx'); quick.ui.alert({ title: "標題", message: "信息", buttonName: "肯定", success: function(result) { // 點擊 alert的按鈕後回調 }, error: function(err) {} });
通常PC瀏覽器中,頁面之間的調整直接經過a標籤
完成(或者改變href
跳轉),
可是這種跳轉有一個缺點:
沒法使用轉場動畫,每次都是乾巴巴的等瀏覽器加載進度條,體驗不好
所以針對這種狀況,原生須要提供特色的API來供頁面調用,能夠有原生轉場動畫,在新的webview中打開這個頁面
quick.page.open({ pageUrl: "./xxx.html", data: { // 額外傳遞的數據 key1: 'value1' }, success: function(result) {}, error: function(error) {} });
採用這種方式打開的頁面再也不是在本webview中跳轉,而是直接用新的webview打開,有過渡動畫,並且之前的頁面仍然存在內存中,接近原生體驗
譬如
頁面A -> 頁面B -> 頁面C
能夠看到,若是是直接調整,頁面A和B是不存存在的,而是會被替換,可是採用原生webview打開後,三個頁面同時存在
雖說能夠有API打開的加強方式,可是仍然須要支持href跳轉,這在集成第三方頁面時十分重要(將已經寫好的第三方純網頁集成到容器中,做爲某個子模塊)
這裏有一點須要注意:
這類頁面通常由a標籤或href跳轉直接打開,沒有轉場動畫,可是須要webview容器保存訪問歷史記錄, 以免屢次跳轉後一個後退就直接退出了整個模塊
當涉及到一些大量計算時,儘可能避免直接在網頁端完成,而是應該由原生提供API完成。
譬如對一張圖片進行圖像處理(曝光、水印、壓縮等等),若是直接由網頁完成的話會發現很是卡,發熱也嚴重,而原生則沒有這麼多的問題
關於底層優化,__其實整套混合開發框架中,底層容器的實現是核心部分__
容器是否健壯,優化的如何,直接影響整個應用的體驗
關於原生容器應該如何進行優化,後續會有專門的文章,這裏不贅述,只是稍微說起一下:
接下來就是在實際開發過程遵循的準則:
乍看之下可能和上述的有矛盾,但其實又是合理的,在排除了一些不適合H5實現的頁面,剩餘的絕大部分都是普通的業務頁面,
這類頁面基本能夠毫無壓力的採用H5。
因此,這時候,第一想法都是採用H5完成(由於一套代碼能夠在至少三個平臺運行-瀏覽器,Android,iOS),
遇到一些比較困難的頁面再去考慮原生實現(從開發效率上,維護代價上,更新方便上都比較麻煩)
那些H5開發中遇到最多的頁面
最後,看下實際開發過程當中遇到的最多的頁面吧(以實際遇到的N
個項目的總結)
沒錯,80%
都是上述這種能夠算很是簡單的頁面。
譬如封裝過一個下拉刷新組件,基本別人基於這個組件來開發,列表的代碼幾乎是千篇一概。(固然了,剝離了業務邏輯而言)
時至今日,Hybrid
模式已通過了它最火的時候,市面上也出現如weex
,react-native
等直接寫原生組件的框架,
可是,如今使用最多,應用最廣的仍然要屬這種傳統的Hybrid模式,它已經進入了穩按期(能夠說,傳統H5開發(泛概念)不被APP淘汰,這種模式很難被擠下舞臺)
github
上這個框架的實現