Skip to content

Commit 1df79e9

Browse files
crisbetoandrewseguin
authored andcommitted
perf(tabs): avoid extra resize handler and reflow (#6434)
In #6304, an extra window resize handler was added in order to call `_checkPaginationEnabled`. This handler is unnecessary, because we have another resize handler a little bit below that calls `_updatePagination`, which will call `_checkPaginationEnabled` internally. The original issue that #6304 was fixing was due to the fact that the current listener wasn't being run in the Angular zone. These changes remove the extra listener, increase the debounce interval and move the handler outside back into the zone. There may be a slight overhead from moving the listener into the zone, however it should be offset by not having another listener and not calling `_checkPaginationEnabled` twice.
1 parent 5d437ea commit 1df79e9

File tree

2 files changed

+21
-40
lines changed

2 files changed

+21
-40
lines changed

src/lib/tabs/tab-header.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ describe('MdTabHeader', () => {
259259
spyOn(inkBar, 'alignToElement');
260260

261261
dispatchFakeEvent(window, 'resize');
262-
tick(10);
262+
tick(150);
263263
fixture.detectChanges();
264264

265265
expect(inkBar.alignToElement).toHaveBeenCalled();

src/lib/tabs/tab-header.ts

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ import {
2020
AfterContentChecked,
2121
AfterContentInit,
2222
OnDestroy,
23-
NgZone,
2423
Renderer2,
2524
ChangeDetectionStrategy,
26-
ChangeDetectorRef
25+
ChangeDetectorRef,
2726
} from '@angular/core';
2827
import {Directionality, Direction} from '@angular/cdk/bidi';
2928
import {RIGHT_ARROW, LEFT_ARROW, ENTER} from '@angular/cdk/keycodes';
@@ -35,8 +34,6 @@ import {fromEvent} from 'rxjs/observable/fromEvent';
3534
import {MdTabLabelWrapper} from './tab-label-wrapper';
3635
import {MdInkBar} from './ink-bar';
3736
import {CanDisableRipple, mixinDisableRipple} from '../core/common-behaviors/disable-ripple';
38-
import {RxChain, debounceTime} from '@angular/cdk/rxjs';
39-
import {Platform} from '@angular/cdk/platform';
4037

4138
/**
4239
* The directions that scrolling can go in when the header's tabs exceed the header width. 'After'
@@ -117,15 +114,11 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
117114

118115
private _selectedIndex: number = 0;
119116

120-
/** subscription for the window resize handler */
121-
private _resizeSubscription: Subscription | null;
122-
123117
/** The index of the active tab. */
124118
@Input()
125119
get selectedIndex(): number { return this._selectedIndex; }
126120
set selectedIndex(value: number) {
127121
this._selectedIndexChanged = this._selectedIndex != value;
128-
129122
this._selectedIndex = value;
130123
this._focusIndex = value;
131124
}
@@ -137,19 +130,10 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
137130
@Output() indexFocused = new EventEmitter();
138131

139132
constructor(private _elementRef: ElementRef,
140-
private _ngZone: NgZone,
141133
private _renderer: Renderer2,
142134
private _changeDetectorRef: ChangeDetectorRef,
143-
@Optional() private _dir: Directionality,
144-
platform: Platform) {
135+
@Optional() private _dir: Directionality) {
145136
super();
146-
147-
if (platform.isBrowser) {
148-
// TODO: Add library level window listener https://goo.gl/y25X5M
149-
this._resizeSubscription = RxChain.from(fromEvent(window, 'resize'))
150-
.call(debounceTime, 150)
151-
.subscribe(() => this._checkPaginationEnabled());
152-
}
153137
}
154138

155139
ngAfterContentChecked(): void {
@@ -197,16 +181,14 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
197181
* Aligns the ink bar to the selected tab on load.
198182
*/
199183
ngAfterContentInit() {
200-
this._realignInkBar = this._ngZone.runOutsideAngular(() => {
201-
let dirChange = this._dir ? this._dir.change : observableOf(null);
202-
let resize = typeof window !== 'undefined' ?
203-
auditTime.call(fromEvent(window, 'resize'), 10) :
204-
observableOf(null);
205-
206-
return startWith.call(merge(dirChange, resize), null).subscribe(() => {
207-
this._updatePagination();
208-
this._alignInkBarToSelectedTab();
209-
});
184+
const dirChange = this._dir ? this._dir.change : observableOf(null);
185+
const resize = typeof window !== 'undefined' ?
186+
auditTime.call(fromEvent(window, 'resize'), 150) :
187+
observableOf(null);
188+
189+
this._realignInkBar = startWith.call(merge(dirChange, resize), null).subscribe(() => {
190+
this._updatePagination();
191+
this._alignInkBarToSelectedTab();
210192
});
211193
}
212194

@@ -215,11 +197,6 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
215197
this._realignInkBar.unsubscribe();
216198
this._realignInkBar = null;
217199
}
218-
219-
if (this._resizeSubscription) {
220-
this._resizeSubscription.unsubscribe();
221-
this._resizeSubscription = null;
222-
}
223200
}
224201

225202
/**
@@ -400,14 +377,18 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
400377
* should be called sparingly.
401378
*/
402379
_checkPaginationEnabled() {
403-
this._showPaginationControls =
380+
const isEnabled =
404381
this._tabList.nativeElement.scrollWidth > this._elementRef.nativeElement.offsetWidth;
405382

406-
if (!this._showPaginationControls) {
383+
if (!isEnabled) {
407384
this.scrollDistance = 0;
408385
}
409386

410-
this._changeDetectorRef.markForCheck();
387+
if (isEnabled !== this._showPaginationControls) {
388+
this._changeDetectorRef.markForCheck();
389+
}
390+
391+
this._showPaginationControls = isEnabled;
411392
}
412393

413394
/**
@@ -441,9 +422,9 @@ export class MdTabHeader extends _MdTabHeaderMixinBase
441422

442423
/** Tells the ink-bar to align itself to the current label wrapper */
443424
private _alignInkBarToSelectedTab(): void {
444-
const selectedLabelWrapper = this._labelWrappers && this._labelWrappers.length
445-
? this._labelWrappers.toArray()[this.selectedIndex].elementRef.nativeElement
446-
: null;
425+
const selectedLabelWrapper = this._labelWrappers && this._labelWrappers.length ?
426+
this._labelWrappers.toArray()[this.selectedIndex].elementRef.nativeElement :
427+
null;
447428

448429
this._inkBar.alignToElement(selectedLabelWrapper);
449430
}

0 commit comments

Comments
 (0)