perf(animations): always run the animation queue outside of zones

Related #12732
Closes #13440
This commit is contained in:
Matias Niemelä
2016-12-09 13:04:18 -08:00
committed by Victor Berchet
parent ecfad467a1
commit e2622add07
17 changed files with 441 additions and 106 deletions

View File

@ -7,14 +7,15 @@
*/
import {AnimationGroupPlayer} from '../animation/animation_group_player';
import {AnimationPlayer} from '../animation/animation_player';
import {queueAnimation as queueAnimationGlobally} from '../animation/animation_queue';
import {AnimationQueue} from '../animation/animation_queue';
import {AnimationSequencePlayer} from '../animation/animation_sequence_player';
import {ViewAnimationMap} from '../animation/view_animation_map';
import {ListWrapper} from '../facade/collection';
export class AnimationViewContext {
private _players = new ViewAnimationMap();
constructor(private _animationQueue: AnimationQueue) {}
onAllActiveAnimationsDone(callback: () => any): void {
const activeAnimationPlayers = this._players.getAllPlayers();
// we check for the length to avoid having GroupAnimationPlayer
@ -27,7 +28,7 @@ export class AnimationViewContext {
}
queueAnimation(element: any, animationName: string, player: AnimationPlayer): void {
queueAnimationGlobally(player);
this._animationQueue.enqueue(player);
this._players.set(element, animationName, player);
player.onDone(() => this._players.remove(element, animationName, player));
}

View File

@ -63,7 +63,7 @@ export abstract class AppView<T> {
public viewUtils: ViewUtils, public parentView: AppView<any>, public parentIndex: number,
public parentElement: any, public cdMode: ChangeDetectorStatus,
public declaredViewContainer: ViewContainer = null) {
this.ref = new ViewRef_(this);
this.ref = new ViewRef_(this, viewUtils.animationQueue);
if (type === ViewType.COMPONENT || type === ViewType.HOST) {
this.renderer = viewUtils.renderComponent(componentType);
} else {
@ -74,7 +74,7 @@ export abstract class AppView<T> {
get animationContext(): AnimationViewContext {
if (!this._animationContext) {
this._animationContext = new AnimationViewContext();
this._animationContext = new AnimationViewContext(this.viewUtils.animationQueue);
}
return this._animationContext;
}

View File

@ -6,14 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/
import {triggerQueuedAnimations} from '../animation/animation_queue';
import {AnimationQueue} from '../animation/animation_queue';
import {ChangeDetectorRef} from '../change_detection/change_detector_ref';
import {ChangeDetectorStatus} from '../change_detection/constants';
import {unimplemented} from '../facade/errors';
import {AppView} from './view';
/**
* @stable
*/
@ -92,7 +90,7 @@ export class ViewRef_<C> implements EmbeddedViewRef<C>, ChangeDetectorRef {
/** @internal */
_originalMode: ChangeDetectorStatus;
constructor(private _view: AppView<C>) {
constructor(private _view: AppView<C>, public animationQueue: AnimationQueue) {
this._view = _view;
this._originalMode = this._view.cdMode;
}
@ -109,7 +107,7 @@ export class ViewRef_<C> implements EmbeddedViewRef<C>, ChangeDetectorRef {
detach(): void { this._view.cdMode = ChangeDetectorStatus.Detached; }
detectChanges(): void {
this._view.detectChanges(false);
triggerQueuedAnimations();
this.animationQueue.flush();
}
checkNoChanges(): void { this._view.detectChanges(true); }
reattach(): void {

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AnimationQueue} from '../animation/animation_queue';
import {SimpleChange, devModeEqual} from '../change_detection/change_detection';
import {UNINITIALIZED} from '../change_detection/change_detection_util';
import {Inject, Injectable} from '../di';
@ -14,17 +15,21 @@ import {ViewEncapsulation} from '../metadata/view';
import {RenderComponentType, RenderDebugInfo, Renderer, RootRenderer} from '../render/api';
import {Sanitizer} from '../security';
import {VERSION} from '../version';
import {NgZone} from '../zone/ng_zone';
import {ExpressionChangedAfterItHasBeenCheckedError} from './errors';
import {AppView} from './view';
import {ViewContainer} from './view_container';
@Injectable()
export class ViewUtils {
sanitizer: Sanitizer;
private _nextCompTypeId: number = 0;
constructor(private _renderer: RootRenderer, sanitizer: Sanitizer) { this.sanitizer = sanitizer; }
constructor(
private _renderer: RootRenderer, sanitizer: Sanitizer,
public animationQueue: AnimationQueue) {
this.sanitizer = sanitizer;
}
/** @internal */
renderComponent(renderComponentType: RenderComponentType): Renderer {