Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 99d088e

Browse files
committed
perf(ngClass): optimize the case of static map of classes with large objects by refactor
1 parent 8643b6a commit 99d088e

File tree

2 files changed

+21
-22
lines changed

2 files changed

+21
-22
lines changed

src/ng/directive/ngClass.js

+20-21
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ function classDirective(name, selector) {
99
link: function(scope, element, attr) {
1010
var oldVal;
1111

12-
// shortcut: if it is clearly a map of classes do not copy values, they are supposed to be boolean (truly/falsy)
13-
scope[staticMapClassRegEx.test(attr[name]) ? '$watchCollection' : '$watch'](attr[name], ngClassWatchAction, true);
12+
scope.$watch(ngClassParseClasses, ngClassWatchAction);
1413

1514
attr.$observe('class', function(value) {
16-
ngClassWatchAction(scope.$eval(attr[name]));
15+
ngClassWatchAction(ngClassParseClasses());
1716
});
1817

1918

@@ -22,7 +21,7 @@ function classDirective(name, selector) {
2221
// jshint bitwise: false
2322
var mod = $index & 1;
2423
if (mod !== (old$index & 1)) {
25-
var classes = arrayClasses(scope.$eval(attr[name]));
24+
var classes = stringClasses(scope.$eval(attr[name])).split(' ');
2625
mod === selector ?
2726
addClasses(classes) :
2827
removeClasses(classes);
@@ -70,17 +69,23 @@ function classDirective(name, selector) {
7069
}
7170
}
7271

72+
function ngClassParseClasses() {
73+
var classVal = scope.$eval(attr[name]);
74+
var classes = stringClasses(classVal);
75+
return classes;
76+
}
77+
7378
function ngClassWatchAction(newVal) {
7479
if (selector === true || scope.$index % 2 === selector) {
75-
var newClasses = arrayClasses(newVal || []);
80+
var newClasses = newVal.split(' ');
7681
if (!oldVal) {
7782
addClasses(newClasses);
78-
} else if (!equals(newVal,oldVal)) {
79-
var oldClasses = arrayClasses(oldVal);
83+
} else {
84+
var oldClasses = oldVal.split(' ');
8085
updateClasses(oldClasses, newClasses);
8186
}
87+
oldVal = newVal;
8288
}
83-
oldVal = shallowCopy(newVal);
8489
}
8590
}
8691
};
@@ -99,24 +104,18 @@ function classDirective(name, selector) {
99104
return values;
100105
}
101106

102-
function arrayClasses(classVal) {
103-
var classes = [];
107+
function stringClasses(classVal) {
108+
var classes;
104109
if (isArray(classVal)) {
105-
forEach(classVal, function(v) {
106-
classes = classes.concat(arrayClasses(v));
107-
});
110+
classes = classVal.map(stringClasses).join(' ');
108111
return classes;
109-
} else if (isString(classVal)) {
110-
return classVal.split(' ');
111112
} else if (isObject(classVal)) {
112-
forEach(classVal, function(v, k) {
113-
if (v) {
114-
classes = classes.concat(k.split(' '));
115-
}
116-
});
113+
classes = Object.keys(classVal).filter(function(k) {
114+
return classVal[k];
115+
}).join(' ');
117116
return classes;
118117
}
119-
return classVal;
118+
return classVal || '';
120119
}
121120
}];
122121
}

test/ng/directive/ngClassSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ describe('ngClass', function() {
415415
$rootScope.verylargeobject = {very: 'largeobject'};
416416
$rootScope.$digest();
417417

418-
expect($rootScope.$$watchers[0].last).toEqual(jasmine.any(Number));
418+
expect(JSON.stringify($rootScope.$$watchers[0].last)).not.toContain('largeobject');
419419
}));
420420

421421
});

0 commit comments

Comments
 (0)