angularjs移除不必要的$watch

简介:

 在我们的web page,特别是移动设备上,太多的angular $watch将可能导致性能问题。这篇文章将解释如何去移除额外的$watch提高你的应用程序性能。

     $watch如果不再使用,我们最好将其释放掉,在angular中我们可以自由的选择在什么时候将$watch$watch列表中移除。

让我们来看个示例:

复制代码
app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {

$scope.updated = 0;

$scope.stop = function() {

textWatch();

};



var textWatch = $scope.$watch('text', function(newVal, oldVal) {

if (newVal === oldVal) { return; }

$scope.updated++;

});

});
复制代码
复制代码
<body ng-controller="MainCtrl">

<input type="text" ng-model="text" /> {{updated}} times updated.

<button ng-click="stop()">Stop count</button>

</body>
复制代码

     $watch函数会返回一个释放$watch绑定的unbind函数。所以当我们不再需要watch改变的时候,我们可以easy的调用这个函数释放$watch

由静态数据构成的页面

   让我假想我们要创建一个会议session预约的页面,页面像如下结构:

复制代码
app.controller('MainCtrl', function($scope) {

$scope.sessions = [...];

$scope.likeSession = function(session) {

// Like the session

}

});
复制代码
复制代码
<ul>

<li ng-repeat="session in sessions">

<div class="info">

{{session.name}} - {{session.room}} - {{session.hour}} - {{session.speaker}}

</div>

<div class="likes">

{{session.likes}} likes! <button ng-click="likeSession(session)">Like it!</button>

</div>

</li>

</ul>
复制代码

     假想这是一个大型的预约,一天会有30sessions。这里会产生多少个$watch?这里每个session5个绑定,额外的ng-repeat一个.这将会产生151$watch。这有什么问题?每次用户“like”一个sessionangular将会去检查name是不是被改变(其他的属性也相同)

    问题在于除了例外的“like”外,所有的数据都是静态数据,这是不是有点浪费资源?我们能够100%保证我们的数据不会改变,既然这样为什么我们让angular要去检查是否改变呢?

   解决方案很简单。我们移除永远不会改变的$watch$watch在第一非常重要,它用静态信息生产更新了我们的DOM结构,但是在此之后,它监听了一个永远不会被改变的常量,这明显是很大的浪费资源。

如果你相信我了的话,会我们能怎么去解决呢?幸运的是,这有个nice guy在我们之前也问了自己这个问题,并创建了一系列的指令实现这个:Bindonce.

Bindonce

   Bindonce是一系列绑定但是不带watch的指令集,这很完美的符合了我们的需求。

让我们用Bindonce重新实现我们的view

复制代码
<ul>

<li bindonce ng-repeat="session in sessions">

<div class="info">

<span bo-text="session.name"></span> -

<span bo-text="session.room"></span> -

<span bo-text="session.hour"></span> -

<span bo-text="session.speaker"></span>

</div>

<div class="likes">

{{session.likes}} likes! <button ng-click="likeSession(session)">Like it!</button>

</div>

</li>

</ul>
复制代码

 

    为了让示例能够工作,我们必须引入bindonce到我们的应用程序。

app = angular.module('app', ['pasvaz.bindonce']);

 

    在这里我们将angular表达式换位了bo-text指令。这指令将会绑定我们的model,知道更新DOM,然后去掉绑定。这样我就可以显示view但是移除不必要的饿绑定了。

   在此例中每个session只有一个$watch绑定,所以这里用31个绑定替代了151个绑定。我们正确的使用bingonce将会为我们的应用程序大量减少$watch绑定。 

总结

   当我们的性能无法避免的需要优化的时候,bindonce能够帮助脱离$watch的性能瓶颈。在bindonce中还有很多的指令,我可以从这里搜索到:https://github.com/Pasvaz/bindonce#attribute-usage


本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/p/angularjs-remove-unused-watch.html,如需转载请自行联系原作者

目录
相关文章
|
11天前
【实用】Angular中如何实现类似Vuex的全局变量状态变化功能?
【实用】Angular中如何实现类似Vuex的全局变量状态变化功能?
|
7月前
|
缓存 监控 JavaScript
关于 Angular SSR 应用在渲染中止时如何避免内存泄漏问题的一些尝试
关于 Angular SSR 应用在渲染中止时如何避免内存泄漏问题的一些尝试
45 0
|
监控 JavaScript 前端开发
angularJS学习小结——$apply方法和$watch方法
angularJS学习小结——$apply方法和$watch方法
90 0
|
JavaScript 前端开发
Angular Component的加载触发时机
Angular Component的加载触发时机
Angular Component的加载触发时机
|
JavaScript 前端开发
Angular 页面元素的DOM级别的删除过程
Angular 页面元素的DOM级别的删除过程
104 0
Angular 页面元素的DOM级别的删除过程
|
JavaScript
关于 Angular Component ngOnDestroy 钩子函数的调用时机
关于 Angular Component ngOnDestroy 钩子函数的调用时机
190 0
关于 Angular Component ngOnDestroy 钩子函数的调用时机
Angular jasmine如何从detectChange触发refreshView进而执行到Component的hook实现
Angular jasmine如何从detectChange触发refreshView进而执行到Component的hook实现
99 0
Angular jasmine如何从detectChange触发refreshView进而执行到Component的hook实现
|
JavaScript 编译器
Angular如何判断某个DOM节点包含Directive
Angular如何判断某个DOM节点包含Directive
Angular如何判断某个DOM节点包含Directive
优化Angularjs的$watch方法
Angularjs的$watch相信大家都知道,而且也经常使用,甚至,你还在为它的某些行为感到恼火。比如,一进入页面,它就会调用一次,我明明希望它在我初始化之后,值再次变动才调用。这种行为给我们带来许多麻烦。
2123 0