Skip to content

perf(sidenav): avoid hitting zone continuously when using autosize option #11231

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions src/lib/sidenav/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,20 @@ export function MAT_DRAWER_DEFAULT_AUTOSIZE_FACTORY(): boolean {
template: '<ng-content></ng-content>',
host: {
'class': 'mat-drawer-content',
'[style.margin-left.px]': '_margins.left',
'[style.margin-right.px]': '_margins.right',
'[style.margin-left.px]': '_container._contentMargins.left',
'[style.margin-right.px]': '_container._contentMargins.right',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MatDrawerContent implements AfterContentInit {
/**
* Margins to be applied to the content. These are used to push / shrink the drawer content when a
* drawer is open. We use margin rather than transform even for push mode because transform breaks
* fixed position elements inside of the transformed element.
*/
_margins: {left: number|null, right: number|null} = {left: null, right: null};

constructor(
private _changeDetectorRef: ChangeDetectorRef,
@Inject(forwardRef(() => MatDrawerContainer)) private _container: MatDrawerContainer) {
@Inject(forwardRef(() => MatDrawerContainer)) public _container: MatDrawerContainer) {
}

ngAfterContentInit() {
this._container._contentMargins.subscribe(margins => {
this._margins = margins;
this._container._contentMarginChanges.subscribe(() => {
this._changeDetectorRef.markForCheck();
});
}
Expand Down Expand Up @@ -466,7 +458,14 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
/** Emits on every ngDoCheck. Used for debouncing reflows. */
private readonly _doCheckSubject = new Subject<void>();

readonly _contentMargins = new Subject<{left: number|null, right: number|null}>();
/**
* Margins to be applied to the content. These are used to push / shrink the drawer content when a
* drawer is open. We use margin rather than transform even for push mode because transform breaks
* fixed position elements inside of the transformed element.
*/
_contentMargins: {left: number|null, right: number|null} = {left: null, right: null};

readonly _contentMarginChanges = new Subject<{left: number|null, right: number|null}>();

/** Reference to the CdkScrollable instance that wraps the scrollable content. */
@ViewChild(CdkScrollable) scrollable: CdkScrollable;
Expand Down Expand Up @@ -699,7 +698,13 @@ export class MatDrawerContainer implements AfterContentInit, OnDestroy {
}
}

// Pull back into the NgZone since in some cases we could be outside.
this._ngZone.run(() => this._contentMargins.next({left, right}));
if (left !== this._contentMargins.left || right !== this._contentMargins.right) {
this._contentMargins = {left, right};

// Pull back into the NgZone since in some cases we could be outside. We need to be careful
// to do it only when something changed, otherwise we can end up hitting the zone too often.
this._ngZone.run(() => this._contentMarginChanges.next(this._contentMargins));
}

}
}
4 changes: 2 additions & 2 deletions src/lib/sidenav/sidenav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import {coerceBooleanProperty, coerceNumberProperty} from '@angular/cdk/coercion
template: '<ng-content></ng-content>',
host: {
'class': 'mat-drawer-content mat-sidenav-content',
'[style.margin-left.px]': '_margins.left',
'[style.margin-right.px]': '_margins.right',
'[style.margin-left.px]': '_container._contentMargins.left',
'[style.margin-right.px]': '_container._contentMargins.right',
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
Expand Down