发表于: 2016-06-17 16:44:42

2 2444


AngularJS性能优化心得

一般来说我们用AngularJS做项目的时候,面对大量的数据会选择做分页,这样限制了数据量,展现数据的效果会好不少,不会出现长时间加载,提升用户体验。但是也会有例外,有时候项目的要求就是一页展示数据,那样面对大量的数据,加载就会有很长的时间,影响用户体验。

在使用angularJS的时候为什么会加载时间偏长呢,因为双向绑定大量数据的时候,AngularJS通过“dirty checking”函数来检测变化。每次检测都会花费时间,所以包含复杂数据结构的大型列表将降低你应用的运行速度。

在我之前做一个项目的时候,就遇到了需要做angularjs性能优化的问题,有个列表展示页面,需要一次性展示全部搜索出的数据,大概100条,每条里面有29个属性,这意味着一页就有2900个双向绑定,100张图片,而且还有点击显示另一页的图表,2页要能互相转换,打开开发者工具(一般来说F12可以直接打开),查看network

 

整个过程大概需要4-5秒,而且商家那边电脑性能也没这么好,我去测的时候他们那边更是需要12-14秒不等。这么长的时间用户体验就很不好了,一般这一整个加载时间最好是在3秒以内。

个人感觉一般整个时间分3部分:

第一部分是请求,就是拿数据过程,如果这个过程超过1S,就需要去找后台协商下,看是不是服务器有什么问题。

第二部分是本地的JS数据运算,属于JS请求回来的数据处理,一般来说前端很少做这个处理,但不排除有的情况,这一部分基本属于请求后回来success里面的运算。如何知道这个部分所消耗的时间呢?可以用console.time()console.timeEnd()方法,记得括号里面要一样,表示这2个是配套的。在使用的时候也记得,一个放你点击函数的开始位置,一个要放你请求的结尾,不要放点击函数的结尾,因为JS是单线程函数,会先执行同步任务(大部分代码,由上而下开始执行),然后才会执行异步任务(如ajax请求,js会将这些操作变为异步,放入异步任务里面)。如果还不是很明白请参考:http://huangtengfei.com/2016/04/single-threaded-of-javascript/#more

第三部分是渲染,一般在network里面会显示空白,如果你的请求和数据处理时间都不多,但是整个请求耗时确很多,那就是渲染时间长了,又或者说页面里面双向绑定太多,超过2500个,那渲染一定会很长。上面3部分就个人感觉,请求一般就1秒左右,一般会很快,数据处理更快,基本没有超过1秒的,就这个项目来说那么多数据也就0.1秒就处理完了,渲染应该是这个项目中最长的了,数据量太大没办法,所以对于这个项目来说,需要减少加载时间,主要就是在减少渲染上面,其实大部分项目应该也是类似的。

在网上搜索了一些关于angularjs性能优化的东西,最后决定用一些比较实用的方法:

1.首先我先把ng-show全换成了ng-if,这样可以使这部分代码可以先不缓存,当触发ng-if的时候才缓存,一定程度上加载速度可以提升不少,因为我是一页显示2页的转换数据,这样一开始我就只加载表格,不用加载图表之类。这里大概加速后速度在3秒多了,大概3.23.8左右。

2.然后我看整个列表有100条数据,每条都有个小图表,我就想过懒加载,懒加载的效果是当图片进入到屏幕滚动条一定高度时才会加载,一般正常情况下,浏览器会一次性把一页里面的所有图片都加载出来,这也是会延长加载时间的行为,所以懒加载会让图片在滚动滚动条进入可视区域的时候才开始加载,也可以做一些提前,在进入可视区域前一段开始加载,基本当进入可视区域的时候就可以直接看到了。但是当我用懒加载时却发现请求时间到了8-9秒左右,后面查看原理个人认为应该是懒加载会获取图片的当前位置,但是我的图片很小,数量确很多,每次循环获取位置也会加长加载速度,所以对这个项目而言,有点得不偿失,暂时去掉,也许还有其他的懒加载插件,只是自己选的不好,以后有空再自己做试验。

3.在看angularjs性能优化的时候,也发现说过滤器要慎用,因为一定程度上过滤器也是要多次循环使用,还不如自己处理好数据直接再显示,所以我又把一些过滤器删掉,然后直接再JS里面对数据做处理再展示,但是在测时间的时候发现这个效果并不是很明显,大概也是3.23.6左右,可以说基本没什么变化。

4.最后做的优化也就是去除双向绑定,其实在数据展示这里大部分数据都是直接展示,不需要双向绑定的随时监控效果,所以去除掉不必要双向绑定,可以加快加载速度,这里一般是使用bindonce这个插件来实现。

bindonce这个插件地址:https://github.com/Pasvaz/bindonce

具体使用:

 

先引用下插件JS

 

总控制器里面引用下

 

然后在Ng-repeat 边上添加bindonce

 

然后把双向绑定的li.index在相应的元素里面用bo-text=li.index写出来。

这个效果也是比较明显的,加速后稳定状态加载速度大概2-2.4秒左右,偶尔有几次到3秒,估计也是因为我这表格数据太多双向绑定太多,所以在使用这个方法的时候提升比较明显。

5.然后就是有一些小技巧吧,像我之前做过的那个项目,有个钻取页面的,就是点击列表上的信息会显示更详细的单个的列表,钻取页有返回回来,一般可能做成在请求一次,但是这样基本又是体验不好的问题,因为又需要加载个2-3秒左右,这里其实可以用

把返还回来的数据window.aaaa(自己命名)=res;相当于在整个项目里面定义了一个aaaa=res,记得千万别弄重复了,在从钻取页面回来的时候就可以直接调用,这样就少了请求的时间了,直接对数据处理和渲染,这样像我之前做过一个项目,回来基本就1.2秒左右就加载好了,体验上就强不少。

最后总结下吧,感觉angularJS性能优化方面还是有很多方法的,但是要考虑实际的情况,像我这个添加懒加载的效果就不好,主要问题还是在数据量大、双向绑定多上面,所以在做ng-show换成ng-if的时候少缓存不少东西和去除双向绑定的时候提升比较明显。

其实我感觉还有个效果应该也会很有效果,但是没有找到相关插件,自己做的时候也没做好,有问题,所以放弃了,其实原理和懒加载一样,既然图片可以懒加载,那我一样可以做数据一起懒加载,一开始我只加载一部分数据,比如1个屏幕多一点的数据,然后当滚动到底,又或者滚动一定距离的时候再又加载一部分,这样其实效果就和分页差不多,自己吧大量数据分批次加载,可以大量减少渲染时间,如果以后自己测试好了,再继续做补充吧。

angularJS的优化大体上就这些吧,感觉优化主要还是要自己找对方向,知道自己项目里面耗时间的是那些东西才能针对的做优化,有的可能像我一样是数据量大,有的可能是图片太多太大,那就是主要做懒加载了。优化也还有一些其他方法,可以参考:  

http://www.tuicool.com/articles/IbeARf

http://developer.51cto.com/art/201309/411277_1.htm



返回列表 返回列表
评论

    分享到