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

Commit f9ff5af

Browse files
committed
perf(ngClass): optimize the case of static map of classes with large objects
1 parent c75fb80 commit f9ff5af

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/ng/directive/ngClass.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
'use strict';
22

33
function classDirective(name, selector) {
4+
var staticMapClassRegEx = /^\s*(::)?\s*\{/;
45
name = 'ngClass' + name;
56
return ['$animate', function($animate) {
67
return {
78
restrict: 'AC',
89
link: function(scope, element, attr) {
910
var oldVal;
1011

11-
scope.$watch(attr[name], ngClassWatchAction, true);
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);
1214

1315
attr.$observe('class', function(value) {
1416
ngClassWatchAction(scope.$eval(attr[name]));

test/ng/directive/ngClassSpec.js

+31
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,37 @@ describe('ngClass', function() {
409409
expect(e2.hasClass('even')).toBeTruthy();
410410
expect(e2.hasClass('odd')).toBeFalsy();
411411
}));
412+
413+
describe('large objects', function() {
414+
415+
var verylargeobject, getProp;
416+
beforeEach(function() {
417+
getProp = jasmine.createSpy('getProp');
418+
verylargeobject = {};
419+
Object.defineProperty(verylargeobject, 'prop', {
420+
get: getProp,
421+
enumerable: true
422+
});
423+
});
424+
425+
it('should not copy large objects via hard map of classes', inject(function($rootScope, $compile) {
426+
element = $compile('<div ng-class="{foo: verylargeobject}"></div>')($rootScope);
427+
$rootScope.verylargeobject = verylargeobject;
428+
$rootScope.$digest();
429+
430+
expect(getProp).not.toHaveBeenCalled();
431+
}));
432+
433+
it('should not copy large objects via hard map of classes in one-time binding', inject(function($rootScope, $compile) {
434+
element = $compile('<div ng-class="::{foo: verylargeobject}"></div>')($rootScope);
435+
$rootScope.verylargeobject = verylargeobject;
436+
$rootScope.$digest();
437+
438+
expect(getProp).not.toHaveBeenCalled();
439+
}));
440+
});
441+
442+
412443
});
413444

414445
describe('ngClass animations', function() {

0 commit comments

Comments
 (0)