对于混合应用而言,性能问题一直被吐槽,虽然设备的内存的不断增大,很大程度上缓解了这个一问题,但是和原生应用来讲还是有很大区别,本人从Phonegap2.x开始,一直的探索和使用混合应用技术。
当时的2.x性能真是不怎么样,首次加载时间也比较长,后来phonegap被apache纳入旗下以后,更名为Cordova,可以说从此以后,性能问题得到了很大的改善,占用内存也越来越小,到如今使用的版本已经变为6.3.0,看得出cordova也一直在尝试缩小与native的差距。
不管一个平台如何,是好,是坏?很大程度上都取决开发人员的技术水平,所以如何开发一个高性能的混合应用成为了至关重要的问题。
对于大部分项目而言,都不是一锤子买卖,很多都是长期项目,长期项目就免不了版本的一次一次的更新迭代,可以业务逻辑变得越来越复杂,页面变的越来越多,动画越来越炫酷,数据量越来越大,面对种种问题,我们都需要解决,所以一个好的优化方案势在必得。
下面,就谈一下,这几年我再混合应用开发过程中尝试的优化方案。
影响速度的根本因素,几乎都在内存上,如果内存消耗过高,应用就会卡顿,甚至闪退现象。
所以建议内存方面应注意, 不要存大量的应用数据在内存中,我们可以选择离线数据库,比如pouchdb,当然部分必要数据还是要存的,看实际需求。
目前离线数据库框架都是基于websql,运行速度非常快, 所以必要情况下,可以选择数据离线存储,避免占用内存,因为混合应用的webview渲染本身已经消耗部分内存了。
由于项目不断变大,势必会导致js bundle文件的不断扩充,文件大了,加载速度也就会变慢, 首要解决方案大概如下:
如果不足以优化,就需要讲JS 文件整合成两个文件,从而使文件变小,不必要的的js bundle 可以使用h5 异步加载,提高效率。
例如:
对于混合应用而言,很难达到htmL view和原生view的无缝对接,也就是说,使用起来恰似是同样的实现方式,在一个栈里边。
但事实, 原生view属于native的栈中,而html view属于另一栈中,两种形式的view分属于不同的世界, 而且在使用js调用原生应用,cordova存在线程阻塞问题。
如果下面这个需求,就不好实现了:
大概是,view1中点击按钮,调用扫描插件view2, 扫描出结果以后启动view3,当在view3点击back按钮,需要在返回扫描产检view2, 扫描插件view2点击back退回view1.
对于这个需求,无论是native 还是 html, 在一个栈中,都不是问题,非常简单,但是,不同栈里,就不太好实现了,当在view3点击back调用插件会阻塞掉线程,即便执行back,也无法回退的,最后,在view2点back 回退时候发现, view3闪一下,马上退回view1。
为了解决这个问题,需要用timeout简单实现一个异步的操作,问题就解决了:
setTimeout(function(){
// to execute the native plugin action. eg. call view2
},100)
动画效果,是用户交互体验的根本,如果动画处理不好,就会使很大的问题。
比如进入一个页面后,需要执行一个大概三秒的动画效果,在这三秒内,可能无法触发任何click事件。
比如transform动画。
所以,当你的app中在进入页面两秒内发现点击事件不生效,你就要考虑一下这个页面是否有没有执行完的动画了。
对于angular这样的框架而言是没有页面缓存技术的, 但是部分应用场景中,页面缓存又在所难免,比如像ios tab view这样的底部导航view,是存在缓存的,如果我们可以取消,会非常不符合ios的设计规范。
从用户角度而言,通常情况这中tab view navigation是不需要重新加载数据的,这样的主页面,几乎时刻存在,从新加载会浪费过多的时间。
这里附上一个ionic的缓存方案:
$stateProvider.state('demo', {
cache:true,
url: '/demo',
template: '',
})
上面代码中,通过路由功能对这个页面做了一个cache功能,同样可以禁止掉。
注意:ionic默认是有页面缓存的哦。
监听操作,非常的好用,开发中带来了很多便利,但是于此同时也带来了一些弊端,即为内存的消耗,如果过多的创建监听,势必会占用很多内存。
所以在某些情况下我们可以避免使用监听操作:
比如:我们需要监听一个input输入框数值的变化:
通常来讲会是如下方案:
$scope.$watch('', function