angularjs的一些优化小技巧


Posted in Javascript onDecember 06, 2014

关于优化ng的手段网上已经有很多了,核心都是从$$watchers这个作用域内部属性说起的,今天我来说点别的,本质还是不变的,因为这是ng的硬伤,不过我相信只要运用合适的手法,这些问题还是可以避免的.

ng简介

angularjs简称ng,是google出品的mvvm框架,此在提高前端项目开发效率(实践中来看确实很能提高开发效率),以控制器,指令,服务来围绕整个项目,内部以独有的DI来解决三层之前的调用问题.更多的详情信息可以参考我之前写的ng源码分析.

ng的硬伤

说到硬伤就要先说下它的简单的数据绑定原理

ng里每个页面上定义的model其实都会在当前作用域下添加一个监听器,内部容器就是$$wachers数组,只要页面任何一个model发生变化了,就会触发作用域内部$digest方法,它会依次查找当前作用域树里的所有model,是保证页面上的模型能得到数据同步,所以这个是非常消耗程序时间的,官方的说法就是当页面上出现2000个监听器时,页面性能就会明显下降.所以要提高ng的性能,就要从这方面入手了.

tip1: 一次绑定

其实这个网上别人已经说过了,这里说下新的用法,ng的1.3.0+的版本已经内置提供了一个语法来支持模型只绑定一次的情况,看下面的例子:
old code

hello

new code
hello

可以看到新的语法就是在model前面加上::,相信这个语法要比网上用的第三方插件要方便的多了.

tip2: $scope.$digest vs $scope.$apply

相信很多人对$apply方法不陌生,它一般用在,当不在ng的环境里执行代码的时候,为了保证页面的数据同步,在代码执行完成之后调用$apply方法会触发内部$digest来检查作用域里所有的模型,其实在它的内部是这样调用的,下面只写出一些代码片段。
...

...

$rootScope.$digest

...

...

所有它其实是调用$rootScope根作用域下的$digest,那么不同作用域下的$digest有什么区别呢?其实最重要的区别就在于

$digest 只深度查找调用方下面所有的模型

所以$scope跟$rootScope相比,要节省掉很多查找模型的时间.

不过想要保证页面上所有模型数据的同步,还是得调用$rootScope的,所以在写代码之前最好想想哪些数据是要同步变化的.

tip3: 尽可能少调用 ng-repeat

ng-repeat默认会创建很多监听器,所以在数据量很大的时候,这个非常消耗页面性能,我觉的只有在当需要经常更新数据列表的时候才需要用ng-repeat,要不然放那么多的监听器在那里也是浪费,这时候可以用ng自带的$interpolate服务来解析一个代码片段,类似于一个静态模板引擎,它的内部主要依赖ng核心解析服务$parse,然后把这些填充数据之后的代码片段直接赋给一个一次性的模型性就可以.

tip4: 尽量在指令里写原生语法

虽然ng提供了很多的指令比如ng-show,ng-hide,其实它们作用就是根据模型的true,false来显示或隐藏一个代码片段,虽然能够很快速的实现业务要求,但是这些指令还是默认会添加监听器,假如这些代码片段存在于一个大的指令里面时,更好的方法是在指令link里编写.show(), .hide()这些类似的jq方法来控制比较好,这样可以节省监听器的数量,类似的还有自带的事件指令,这些其实都可以在外围指令里通过使用addEventListener来绑定事件,反正在写代码之前,最好想想怎么样来使监听器的数量最少,这样才能全面的提高页面性能.

tip5: 页面内尽量少用filters

当在页面内的模型后面增加filter时,这个会造成当前模型在$digest里运行两次,造成不必要的性能浪费.第一次在$$watchers检测任务改变时;第二次发生在模型值修改时,所以尽量少用内联时的过滤器语法,像下面这样的非常影响页面性能

推荐使用$filter服务来调用某个过滤器函数在后台,这样能明显的提高页面性能,代码如下

$filter('filter')(array, expression, comparator);

总结

上面都是些提高ng项目性能的一些小技巧,虽然ng很强大,但是不规范的代码也会破坏它的性能,所以在写代码之前最好构思下哪些地方是不需要监听器的.

Javascript 相关文章推荐
csdn 博客的css样式 v3
Feb 24 Javascript
javascript中的=等号个数问题两个跟三个有什么区别
Oct 23 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
Apr 02 Javascript
JS实现样式清新的横排下拉菜单效果
Oct 09 Javascript
基于jquery实现图片上传本地预览功能
Jan 08 Javascript
详解BootStrap中Affix控件的使用及保持布局的美观的方法
Jul 08 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
Oct 18 Javascript
Node.js连接MongoDB数据库产生的问题
Feb 08 Javascript
vue2.0项目中使用Ueditor富文本编辑器示例代码
Aug 14 Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
May 08 Javascript
使用PDF.js渲染canvas实现预览pdf的效果示例
Apr 17 Javascript
JavaScript开发人员的10个关键习惯小结
Dec 05 #Javascript
node.js中RPC(远程过程调用)的实现原理介绍
Dec 05 #Javascript
node.js中实现同步操作的3种实现方法
Dec 05 #Javascript
node.js实现BigPipe详解
Dec 05 #Javascript
js实现点击添加一个input节点
Dec 05 #Javascript
Node.js实现的简易网页抓取功能示例
Dec 05 #Javascript
浅谈js的setInterval事件
Dec 05 #Javascript
You might like
千呼万唤始出来,DOTA2勇士令状不朽宝藏Ⅱ现已推出
2020/08/25 DOTA
PHP解析html类库simple_html_dom的转码bug
2014/05/22 PHP
分享最受欢迎的5款PHP框架
2014/11/27 PHP
浅谈PHP中new self()和new static()的区别
2017/08/11 PHP
javascript学习笔记(三) String 字符串类型介绍
2012/06/19 Javascript
javascript分页代码(当前页码居中)
2012/09/20 Javascript
JavaScript 参数中的数组展开 [译]
2012/09/21 Javascript
Jquery实现搜索框提示功能示例代码
2013/08/13 Javascript
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
js中直接声明一个对象的方法
2014/08/10 Javascript
js 加密压缩出现bug解决方案
2014/11/25 Javascript
基于JavaScript怎么实现让歌词滚动播放
2015/11/03 Javascript
JS判断是否长按某一键的方法
2016/03/02 Javascript
jQuery表单事件实例代码分享
2016/08/18 Javascript
JavaScript实现图片切换效果
2017/08/12 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
vue2.0 实现页面导航提示引导的方法
2018/03/13 Javascript
js实现时钟定时器
2020/03/26 Javascript
[01:00:14]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第三场
2018/04/10 DOTA
使用Python脚本在Linux下实现部分Bash Shell的教程
2015/04/17 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
Python字符串格式化常用手段及注意事项
2020/06/17 Python
Python调用jar包方法实现过程解析
2020/08/11 Python
python 密码学示例——凯撒密码的实现
2020/09/21 Python
英国人最爱的饰品网站:Accessorize
2016/08/22 全球购物
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
英语生日邀请函
2014/01/23 职场文书
小区门卫管理制度
2014/01/29 职场文书
中班幼儿评语大全
2014/04/30 职场文书
小学六一儿童节活动方案
2014/08/27 职场文书
2015年维修电工工作总结
2015/04/25 职场文书
心灵点滴观后感
2015/06/02 职场文书
2016年党建工作简报
2015/11/26 职场文书
解析在浏览器地址栏输入一个URL后发生了什么
2021/06/21 Servers
MySQL串行化隔离级别(间隙锁实现)
2022/06/16 MySQL
pytest实现多进程与多线程运行超好用的插件
2022/07/15 Python