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

Commit 77eb8e1

Browse files
committed
perf(jqLite): avoid setting class attribute when not changed
1 parent 007a7ef commit 77eb8e1

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/jqLite.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,29 +422,35 @@ function jqLiteRemoveClass(element, cssClasses) {
422422
if (cssClasses && element.setAttribute) {
423423
var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
424424
.replace(/[\n\t]/g, ' ');
425+
var newClasses = existingClasses;
425426

426427
forEach(cssClasses.split(' '), function(cssClass) {
427428
cssClass = trim(cssClass);
428-
existingClasses = existingClasses.replace(' ' + cssClass + ' ', ' ');
429+
newClasses = newClasses.replace(' ' + cssClass + ' ', ' ');
429430
});
430431

431-
element.setAttribute('class', trim(existingClasses));
432+
if (newClasses !== existingClasses) {
433+
element.setAttribute('class', trim(newClasses));
434+
}
432435
}
433436
}
434437

435438
function jqLiteAddClass(element, cssClasses) {
436439
if (cssClasses && element.setAttribute) {
437440
var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
438441
.replace(/[\n\t]/g, ' ');
442+
var newClasses = existingClasses;
439443

440444
forEach(cssClasses.split(' '), function(cssClass) {
441445
cssClass = trim(cssClass);
442-
if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
443-
existingClasses += cssClass + ' ';
446+
if (newClasses.indexOf(' ' + cssClass + ' ') === -1) {
447+
newClasses += cssClass + ' ';
444448
}
445449
});
446450

447-
element.setAttribute('class', trim(existingClasses));
451+
if (newClasses !== existingClasses) {
452+
element.setAttribute('class', trim(newClasses));
453+
}
448454
}
449455
}
450456

test/jqLiteSpec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,20 @@ describe('jqLite', function() {
928928
});
929929

930930

931+
it('should not set the attribute when classes not changed', function() {
932+
var fakeElement = {
933+
nodeType: 1,
934+
setAttribute: jasmine.createSpy(),
935+
getAttribute: jasmine.createSpy().and.returnValue('foo bar')
936+
};
937+
var jqA = jqLite(fakeElement);
938+
939+
jqA.addClass('foo');
940+
expect(fakeElement.getAttribute).toHaveBeenCalledOnceWith('class');
941+
expect(fakeElement.setAttribute).not.toHaveBeenCalled();
942+
});
943+
944+
931945
it('should not add duplicate classes', function() {
932946
var jqA = jqLite(a);
933947
expect(a.className).toBe('');
@@ -1059,6 +1073,20 @@ describe('jqLite', function() {
10591073
expect(fakeElement.getAttribute).toHaveBeenCalledOnceWith('class');
10601074
expect(fakeElement.setAttribute).toHaveBeenCalledOnceWith('class', 'bar');
10611075
});
1076+
1077+
1078+
it('should not set the attribute when classes not changed', function() {
1079+
var fakeElement = {
1080+
nodeType: 1,
1081+
setAttribute: jasmine.createSpy(),
1082+
getAttribute: jasmine.createSpy().and.returnValue('foo bar')
1083+
};
1084+
var jqA = jqLite(fakeElement);
1085+
1086+
jqA.removeClass('noexistent');
1087+
expect(fakeElement.getAttribute).toHaveBeenCalledOnceWith('class');
1088+
expect(fakeElement.setAttribute).not.toHaveBeenCalled();
1089+
});
10621090
});
10631091
});
10641092

0 commit comments

Comments
 (0)