parse 和 $interpolate
优化可以调用 $parse 一次然后将其返回的函数
这个函数可以被$eval调用多次,如下
- 优化前
for (let index = 0; index < 9999; index++) {
$scope.$eval('exp')
}
- 优化后
var parsedExp = $parse('exp')
for (let index = 0; index < 9999; index++) {
parsedExp($scope)
}
- 优化前
myApp.directive(function(){
return{
link:function(scope, element, attr){
scope.name = scope.$eval(attr.name);
scope.$watch(attr.list, function(list){
//代码
},true);
}
}
})
- 优化后
myApp.directive(function($parse){
return{
//这里避免使用 link 因为如果这个 directive在循环体中
//使用,这个 link 可能多次执行,而 compile 仅被执行
//一次。
compile:function(elem, attr){
var nameExp = $parse(attr.name),
listExp = $parse(attr.list);
return function link(scope, elem){
//当要观察一个数组或对象时,使用 $watchCollection 代替 $watch
scope.$watchCollection(listExp,function(list){
//代码
})
}
}
}
})
interpolate 速度快的,尽量作为首选
如果没有必要尽量不要使用 $watch
通常会使用 $watch 来观察一个对象内部深层的属性,如果这样
不要观察整个对象,剥去不管紧要的层,只关注要观察的属性即可
- 优化前
$scope.$watch('listOfBigObjects',myHandler, true);
- 优化后
$scope.$watch(function($scope){
return $scope.listOfBigObjects.map(function(bigObject){
return bigObject.name.submane;
})
},myHandler, true)
使用 ng-repeat 时需要使用 track by $index
默认情况(也就是不使用 track by $index 时),ng-repeat 为每个遍历对象
创建一个 dom 节点然后remove后销毁它,
而使用 track by $index 会进创建一次 dom 节点,然后复用它
- 优化前
<div ng-repeat="item in array">
{{item}} 创建一个 dom
</div>
- 优化后
<div ng-repeat="item in array track by $index">
{{item}} 仅创建一个 dom
</div>
ng-show 和 ng-if
ng-show接收的一个bool值,当为true的时候就会被触发去展示DOM节点。
当ng-show的值为false的时候,在DOM节点上添加了一个ng-hide的一个类,
这个类的表达式就是“display:none”。
DOM load的时候ng-show里面的所有节点都会被加载。
也就是说,ng-show仅仅是影藏和显示了DOM节点。
也就意味如果油太多的ng-show指令,即使他们不显示,但他们所在的DOM节点还是会被渲染的。
ng-if也接收的一个bool值,当它的值为false的时候,
它所控制的节点并没有被创建或者说之前的DOM节点会被销毁掉,
哪怕这个节点里面包含了很多ng的绑定都不会去执行。
所以,我们在项目开发中,如果没有必要一次性加载完的dom就可以用
ng-if来阻止ng事件发生,从而也就加快了dom的加载速度。
特别是在repeat的时候,每条数据又包含了复杂的数据结构的时候效果特别明显。
当它的值为true的时候,就会去创建DOM节点。
可以使用仅绑定一次
- 绑定一次
var watcher = $scope.$watch('data', function(newValue, oldValue) {
if (newValue) {
watcher();
}
});
网友评论