Skip to content

Commit 1a67107

Browse files
crisbetoandrewseguin
authored andcommitted
perf(ripple): avoid triggering change detection (#3066)
* perf(ripple): avoid triggering change detection Prevents the ripple event handlers from triggering change detection. Related to #2985. * chore: rename test
1 parent 5cdeb75 commit 1a67107

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

src/lib/core/ripple/ripple-renderer.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,20 @@ export class RippleRenderer {
132132

133133
if (element) {
134134
// If the element is not null, register all event listeners on the trigger element.
135-
this._triggerEvents.forEach((fn, type) => element.addEventListener(type, fn));
135+
this._ngZone.runOutsideAngular(() => {
136+
this._triggerEvents.forEach((fn, type) => element.addEventListener(type, fn));
137+
});
136138
}
137139

138140
this._triggerElement = element;
139141
}
140142

141143
/** Listener being called on mousedown event. */
142144
private onMousedown(event: MouseEvent) {
143-
if (this.rippleDisabled) {
144-
return;
145+
if (!this.rippleDisabled) {
146+
this._isMousedown = true;
147+
this.fadeInRipple(event.pageX, event.pageY, this.rippleConfig);
145148
}
146-
147-
this._isMousedown = true;
148-
this.fadeInRipple(event.pageX, event.pageY, this.rippleConfig);
149149
}
150150

151151
/** Listener being called on mouseup event. */

src/lib/core/ripple/ripple.spec.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ describe('MdRipple', () => {
167167
expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);
168168
});
169169

170+
it('does not run events inside the NgZone', () => {
171+
const spy = jasmine.createSpy('zone unstable callback');
172+
const subscription = fixture.ngZone.onUnstable.subscribe(spy);
173+
174+
dispatchMouseEvent('mousedown');
175+
dispatchMouseEvent('mouseup');
176+
177+
expect(spy).not.toHaveBeenCalled();
178+
subscription.unsubscribe();
179+
});
180+
170181
describe('when page is scrolled', () => {
171182
const startingWindowWidth = window.innerWidth;
172183
const startingWindowHeight = window.innerHeight;
@@ -374,7 +385,7 @@ describe('MdRipple', () => {
374385

375386
@Component({
376387
template: `
377-
<div id="container" mat-ripple [mdRippleSpeedFactor]="0"
388+
<div id="container" mat-ripple [mdRippleSpeedFactor]="0"
378389
style="position: relative; width:300px; height:200px;">
379390
</div>
380391
`,
@@ -387,7 +398,7 @@ class BasicRippleContainer {
387398
template: `
388399
<div id="container" style="position: relative; width:300px; height:200px;"
389400
mat-ripple
390-
[mdRippleSpeedFactor]="0"
401+
[mdRippleSpeedFactor]="0"
391402
[mdRippleTrigger]="trigger"
392403
[mdRippleCentered]="centered"
393404
[mdRippleRadius]="radius"
@@ -406,7 +417,7 @@ class RippleContainerWithInputBindings {
406417
@ViewChild(MdRipple) ripple: MdRipple;
407418
}
408419

409-
@Component({ template: `<div id="container" mat-ripple [mdRippleSpeedFactor]="0"
420+
@Component({ template: `<div id="container" mat-ripple [mdRippleSpeedFactor]="0"
410421
*ngIf="!isDestroyed"></div>` })
411422
class RippleContainerWithNgIf {
412423
@ViewChild(MdRipple) ripple: MdRipple;

0 commit comments

Comments
 (0)