Permalink
Browse files

perf(animations): reduce size of bundle by removing AST classes (#19539)

This CL refactors the animation AST code to make use of interfaces instead of classes. Given that interfaces are not persisted during runtime the removal of classes should nicely cut down on size for the animations-browser bundle.

-- before --
animations-browser.umd.js = 222kb
animations-browser.umd.min.js = 107kb

-- after --
animations-browser.umd.js = 213kb
animations-browser.umd.min.js = 102kb

PR Close #19539
  • Loading branch information...
matsko authored and chuckjaz committed Oct 3, 2017
1 parent f83989b commit d5c9c5f183b1832d437a3307d2f367721f9d0136
@@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {AnimationMetadata, AnimationOptions, ɵStyleData} from '@angular/animations'; import {AnimationMetadata, AnimationMetadataType, AnimationOptions, ɵStyleData} from '@angular/animations';
import {AnimationDriver} from '../render/animation_driver'; import {AnimationDriver} from '../render/animation_driver';
import {normalizeStyles} from '../util'; import {normalizeStyles} from '../util';
@@ -17,7 +17,7 @@ import {AnimationTimelineInstruction} from './animation_timeline_instruction';
import {ElementInstructionMap} from './element_instruction_map'; import {ElementInstructionMap} from './element_instruction_map';
export class Animation { export class Animation {
private _animationAst: Ast; private _animationAst: Ast<AnimationMetadataType>;
constructor(private _driver: AnimationDriver, input: AnimationMetadata|AnimationMetadata[]) { constructor(private _driver: AnimationDriver, input: AnimationMetadata|AnimationMetadata[]) {
const errors: any[] = []; const errors: any[] = [];
const ast = buildAnimationAst(_driver, input, errors); const ast = buildAnimationAst(_driver, input, errors);
@@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {AnimateTimings, AnimationOptions, ɵStyleData} from '@angular/animations'; import {AnimateTimings, AnimationMetadataType, AnimationOptions, ɵStyleData} from '@angular/animations';
const EMPTY_ANIMATION_OPTIONS: AnimationOptions = {}; const EMPTY_ANIMATION_OPTIONS: AnimationOptions = {};
@@ -23,129 +23,90 @@ export interface AstVisitor {
visitAnimateRef(ast: AnimateRefAst, context: any): any; visitAnimateRef(ast: AnimateRefAst, context: any): any;
visitQuery(ast: QueryAst, context: any): any; visitQuery(ast: QueryAst, context: any): any;
visitStagger(ast: StaggerAst, context: any): any; visitStagger(ast: StaggerAst, context: any): any;
visitTiming(ast: TimingAst, context: any): any;
} }
export abstract class Ast { export interface Ast<T extends AnimationMetadataType> {
abstract visit(ast: AstVisitor, context: any): any; type: T;
public options: AnimationOptions = EMPTY_ANIMATION_OPTIONS; options: AnimationOptions|null;
get params(): {[name: string]: any}|null { return this.options['params'] || null; }
}
export class TriggerAst extends Ast {
public queryCount: number = 0;
public depCount: number = 0;
constructor(public name: string, public states: StateAst[], public transitions: TransitionAst[]) {
super();
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitTrigger(this, context); }
} }
export class StateAst extends Ast { export interface TriggerAst extends Ast<AnimationMetadataType.Trigger> {
constructor(public name: string, public style: StyleAst) { super(); } type: AnimationMetadataType.Trigger;
name: string;
visit(visitor: AstVisitor, context: any): any { return visitor.visitState(this, context); } states: StateAst[];
transitions: TransitionAst[];
queryCount: number;
depCount: number;
} }
export class TransitionAst extends Ast { export interface StateAst extends Ast<AnimationMetadataType.State> {
public queryCount: number = 0; type: AnimationMetadataType.State;
public depCount: number = 0; name: string;
style: StyleAst;
constructor(
public matchers: ((fromState: string, toState: string) => boolean)[], public animation: Ast) {
super();
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitTransition(this, context); }
}
export class SequenceAst extends Ast {
constructor(public steps: Ast[]) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitSequence(this, context); }
} }
export class GroupAst extends Ast { export interface TransitionAst extends Ast<AnimationMetadataType.Transition> {
constructor(public steps: Ast[]) { super(); } matchers: ((fromState: string, toState: string) => boolean)[];
animation: Ast<AnimationMetadataType>;
visit(visitor: AstVisitor, context: any): any { return visitor.visitGroup(this, context); } queryCount: number;
depCount: number;
} }
export class AnimateAst extends Ast { export interface SequenceAst extends Ast<AnimationMetadataType.Sequence> {
constructor(public timings: TimingAst, public style: StyleAst|KeyframesAst) { super(); } steps: Ast<AnimationMetadataType>[];
visit(visitor: AstVisitor, context: any): any { return visitor.visitAnimate(this, context); }
} }
export class StyleAst extends Ast { export interface GroupAst extends Ast<AnimationMetadataType.Group> {
public isEmptyStep = false; steps: Ast<AnimationMetadataType>[];
public containsDynamicStyles = false;
constructor(
public styles:StyleData|string)[], public easing: string|null,
public offset: number|null) {
super();
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitStyle(this, context); }
} }
export class KeyframesAst extends Ast { export interface AnimateAst extends Ast<AnimationMetadataType.Animate> {
constructor(public styles: StyleAst[]) { super(); } timings: TimingAst;
style: StyleAst|KeyframesAst;
visit(visitor: AstVisitor, context: any): any { return visitor.visitKeyframes(this, context); }
} }
export class ReferenceAst extends Ast { export interface StyleAst extends Ast<AnimationMetadataType.Style> {
constructor(public animation: Ast) { super(); } styles:StyleData|string)[];
easing: string|null;
visit(visitor: AstVisitor, context: any): any { return visitor.visitReference(this, context); } offset: number|null;
containsDynamicStyles: boolean;
isEmptyStep?: boolean;
} }
export class AnimateChildAst extends Ast { export interface KeyframesAst extends Ast<AnimationMetadataType.Keyframes> { styles: StyleAst[]; }
constructor() { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitAnimateChild(this, context); } export interface ReferenceAst extends Ast<AnimationMetadataType.Reference> {
animation: Ast<AnimationMetadataType>;
} }
export class AnimateRefAst extends Ast { export interface AnimateChildAst extends Ast<AnimationMetadataType.AnimateChild> {}
constructor(public animation: ReferenceAst) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitAnimateRef(this, context); } export interface AnimateRefAst extends Ast<AnimationMetadataType.AnimateRef> {
animation: ReferenceAst;
} }
export class QueryAst extends Ast { export interface QueryAst extends Ast<AnimationMetadataType.Query> {
public originalSelector: string; selector: string;
limit: number;
constructor( optional: boolean;
public selector: string, public limit: number, public optional: boolean, includeSelf: boolean;
public includeSelf: boolean, public animation: Ast) { animation: Ast<AnimationMetadataType>;
super(); originalSelector: string;
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitQuery(this, context); }
} }
export class StaggerAst extends Ast { export interface StaggerAst extends Ast<AnimationMetadataType.Stagger> {
constructor(public timings: AnimateTimings, public animation: Ast) { super(); } timings: AnimateTimings;
animation: Ast<AnimationMetadataType>;
visit(visitor: AstVisitor, context: any): any { return visitor.visitStagger(this, context); }
} }
export class TimingAst extends Ast { export interface TimingAst {
constructor( duration: number;
public duration: number, public delay: number = 0, public easing: string|null = null) { delay: number;
super(); easing: string|null;
} dynamic?: boolean;
visit(visitor: AstVisitor, context: any): any { return visitor.visitTiming(this, context); }
} }
export class DynamicTimingAst extends TimingAst { export interface DynamicTimingAst extends TimingAst {
constructor(public value: string) { super(0, 0, ''); } strValue: string;
dynamic: true;
visit(visitor: AstVisitor, context: any): any { return visitor.visitTiming(this, context); }
} }
Oops, something went wrong.

0 comments on commit d5c9c5f

Please sign in to comment.