perf(angular): skip zone

This commit is contained in:
Manu Mtz.-Almeida
2019-07-06 19:33:34 +02:00
parent 7953088418
commit e059fc8048
19 changed files with 137 additions and 131 deletions

View File

@@ -42,16 +42,14 @@ export class ValueAccessor implements ControlValueAccessor {
}
export function setIonicClasses(element: ElementRef) {
requestAnimationFrame(() => {
const input = element.nativeElement as HTMLElement;
const classes = getClasses(input);
setClasses(input, classes);
const input = element.nativeElement as HTMLElement;
const classes = getClasses(input);
setClasses(input, classes);
const item = input.closest('ion-item');
if (item) {
setClasses(item, classes);
}
});
const item = input.closest('ion-item');
if (item) {
setClasses(item, classes);
}
}
function getClasses(element: HTMLElement) {

View File

@@ -1,5 +1,5 @@
import { Location } from '@angular/common';
import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
import { Attribute, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, filter, switchMap } from 'rxjs/operators';
@@ -57,7 +57,6 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
private resolver: ComponentFactoryResolver,
@Attribute('name') name: string,
@Optional() @Attribute('tabs') tabs: string,
private changeDetector: ChangeDetectorRef,
private config: Config,
private navCtrl: NavController,
commonLocation: Location,
@@ -206,12 +205,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
// Calling `markForCheck` to make sure we will run the change detection when the
// `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
enteringView = this.stackCtrl.createView(this.activated, activatedRoute);
enteringView.ref.changeDetectorRef.detectChanges();
// Store references to the proxy by component
this.proxyMap.set(cmpRef.instance, activatedRouteProxy);
this.currentActivatedRoute$.next({ component: cmpRef.instance, activatedRoute });
this.changeDetector.markForCheck();
}
this.activatedView = enteringView;

View File

@@ -44,11 +44,7 @@ export class StackController {
getExistingView(activatedRoute: ActivatedRoute): RouteView | undefined {
const activatedUrlKey = getUrl(this.router, activatedRoute);
const view = this.views.find(vw => vw.url === activatedUrlKey);
if (view) {
view.ref.changeDetectorRef.reattach();
}
return view;
return this.views.find(vw => vw.url === activatedUrlKey);
}
setActive(enteringView: RouteView): Promise<StackEvent> {
@@ -95,15 +91,15 @@ export class StackController {
}
const views = this.insertView(enteringView, direction);
return this.wait(async () => {
await this.transition(enteringView, leavingView, animation, this.canGoBack(1), false);
await cleanupAsync(enteringView, views, viewsSnapshot, this.location);
return {
enteringView,
direction,
animation,
tabSwitch
};
return this.wait(() => {
return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false)
.then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location))
.then(() => ({
enteringView,
direction,
animation,
tabSwitch
}));
});
}
@@ -138,13 +134,12 @@ export class StackController {
});
}
async startBackTransition() {
startBackTransition() {
const leavingView = this.activeView;
if (leavingView) {
const views = this.getStack(leavingView.stackId);
const enteringView = views[views.length - 2];
enteringView.ref.changeDetectorRef.reattach();
await this.wait(() => {
return this.wait(() => {
return this.transition(
enteringView, // entering view
leavingView, // leaving view
@@ -154,6 +149,7 @@ export class StackController {
);
});
}
return Promise.resolve();
}
endBackTransition(shouldComplete: boolean) {
@@ -189,7 +185,7 @@ export class StackController {
return this.views.slice();
}
private async transition(
private transition(
enteringView: RouteView | undefined,
leavingView: RouteView | undefined,
direction: 'forward' | 'back' | undefined,
@@ -198,7 +194,13 @@ export class StackController {
) {
if (this.skipTransition) {
this.skipTransition = false;
return;
return Promise.resolve(false);
}
if (enteringView) {
enteringView.ref.changeDetectorRef.reattach();
}
if (leavingView) {
leavingView.ref.changeDetectorRef.detach();
}
const enteringEl = enteringView ? enteringView.element : undefined;
const leavingEl = leavingView ? leavingView.element : undefined;
@@ -209,15 +211,15 @@ export class StackController {
containerEl.appendChild(enteringEl);
}
await containerEl.componentOnReady();
await containerEl.commit(enteringEl, leavingEl, {
return this.zone.runOutsideAngular(() => containerEl.commit(enteringEl, leavingEl, {
deepWait: true,
duration: direction === undefined ? 0 : undefined,
direction,
showGoBack,
progressAnimation
});
}));
}
return Promise.resolve(false);
}
private async wait<T>(task: () => Promise<T>): Promise<T> {
@@ -245,7 +247,6 @@ function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: Rout
.forEach(destroyView);
views.forEach(view => {
/**
* In the event that a user navigated multiple
* times in rapid succession, we want to make sure