在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
上这个框架的实现