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
* 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 {normalizeStyles} from '../util';
@@ -17,7 +17,7 @@ import {AnimationTimelineInstruction} from './animation_timeline_instruction';
import {ElementInstructionMap} from './element_instruction_map';
export class Animation {
private _animationAst: Ast;
private _animationAst: Ast<AnimationMetadataType>;
constructor(private _driver: AnimationDriver, input: AnimationMetadata|AnimationMetadata[]) {
const errors: any[] = [];
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
* 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 = {};
@@ -23,129 +23,90 @@ export interface AstVisitor {
visitAnimateRef(ast: AnimateRefAst, context: any): any;
visitQuery(ast: QueryAst, context: any): any;
visitStagger(ast: StaggerAst, context: any): any;
visitTiming(ast: TimingAst, context: any): any;
}
export abstract class Ast {
abstract visit(ast: AstVisitor, context: any): any;
public options: AnimationOptions = EMPTY_ANIMATION_OPTIONS;
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 interface Ast<T extends AnimationMetadataType> {
type: T;
options: AnimationOptions|null;
}
export class StateAst extends Ast {
constructor(public name: string, public style: StyleAst) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitState(this, context); }
export interface TriggerAst extends Ast<AnimationMetadataType.Trigger> {
type: AnimationMetadataType.Trigger;
name: string;
states: StateAst[];
transitions: TransitionAst[];
queryCount: number;
depCount: number;
}
export class TransitionAst extends Ast {
public queryCount: number = 0;
public depCount: number = 0;
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 interface StateAst extends Ast<AnimationMetadataType.State> {
type: AnimationMetadataType.State;
name: string;
style: StyleAst;
}
export class GroupAst extends Ast {
constructor(public steps: Ast[]) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitGroup(this, context); }
export interface TransitionAst extends Ast<AnimationMetadataType.Transition> {
matchers: ((fromState: string, toState: string) => boolean)[];
animation: Ast<AnimationMetadataType>;
queryCount: number;
depCount: number;
}
export class AnimateAst extends Ast {
constructor(public timings: TimingAst, public style: StyleAst|KeyframesAst) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitAnimate(this, context); }
export interface SequenceAst extends Ast<AnimationMetadataType.Sequence> {
steps: Ast<AnimationMetadataType>[];
}
export class StyleAst extends Ast {
public isEmptyStep = false;
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 interface GroupAst extends Ast<AnimationMetadataType.Group> {
steps: Ast<AnimationMetadataType>[];
}
export class KeyframesAst extends Ast {
constructor(public styles: StyleAst[]) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitKeyframes(this, context); }
export interface AnimateAst extends Ast<AnimationMetadataType.Animate> {
timings: TimingAst;
style: StyleAst|KeyframesAst;
}
export class ReferenceAst extends Ast {
constructor(public animation: Ast) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitReference(this, context); }
export interface StyleAst extends Ast<AnimationMetadataType.Style> {
styles:StyleData|string)[];
easing: string|null;
offset: number|null;
containsDynamicStyles: boolean;
isEmptyStep?: boolean;
}
export class AnimateChildAst extends Ast {
constructor() { super(); }
export interface KeyframesAst extends Ast<AnimationMetadataType.Keyframes> { styles: StyleAst[]; }
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 {
constructor(public animation: ReferenceAst) { super(); }
export interface AnimateChildAst extends Ast<AnimationMetadataType.AnimateChild> {}
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 {
public originalSelector: string;
constructor(
public selector: string, public limit: number, public optional: boolean,
public includeSelf: boolean, public animation: Ast) {
super();
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitQuery(this, context); }
export interface QueryAst extends Ast<AnimationMetadataType.Query> {
selector: string;
limit: number;
optional: boolean;
includeSelf: boolean;
animation: Ast<AnimationMetadataType>;
originalSelector: string;
}
export class StaggerAst extends Ast {
constructor(public timings: AnimateTimings, public animation: Ast) { super(); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitStagger(this, context); }
export interface StaggerAst extends Ast<AnimationMetadataType.Stagger> {
timings: AnimateTimings;
animation: Ast<AnimationMetadataType>;
}
export class TimingAst extends Ast {
constructor(
public duration: number, public delay: number = 0, public easing: string|null = null) {
super();
}
visit(visitor: AstVisitor, context: any): any { return visitor.visitTiming(this, context); }
export interface TimingAst {
duration: number;
delay: number;
easing: string|null;
dynamic?: boolean;
}
export class DynamicTimingAst extends TimingAst {
constructor(public value: string) { super(0, 0, ''); }
visit(visitor: AstVisitor, context: any): any { return visitor.visitTiming(this, context); }
export interface DynamicTimingAst extends TimingAst {
strValue: string;
dynamic: true;
}
Oops, something went wrong.

0 comments on commit d5c9c5f

Please sign in to comment.