From 3cb37e0ca8705375419df0b67d84cbbeb2e54311 Mon Sep 17 00:00:00 2001 From: Colin Meinke Date: Thu, 14 Sep 2017 18:30:30 -0500 Subject: [PATCH] fix(performance): reduce object creation Refs colinmeinke/wilderness#71 --- src/clone.js | 17 +++++++++++++---- src/color-middleware.js | 4 +++- src/frame.js | 33 +++++++++++++++++---------------- src/middleware.js | 36 +++++++++++++++++++++++++++--------- 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/clone.js b/src/clone.js index 4238bc8..51b7ae6 100644 --- a/src/clone.js +++ b/src/clone.js @@ -10,12 +10,21 @@ */ const clone = value => { if (Array.isArray(value)) { - return value.map(x => clone(x)) + const arr = [] + + for (let i = 0, l = value.length; i < l; i++) { + arr.push(clone(value[ i ])) + } + + return arr } else if (value !== null && typeof value === 'object') { - return Object.keys(value).reduce((obj, key) => { + const obj = {} + + for (let key in value) { obj[ key ] = clone(value[ key ]) - return obj - }, {}) + } + + return obj } return value diff --git a/src/color-middleware.js b/src/color-middleware.js index 9e5582b..4d8ede9 100644 --- a/src/color-middleware.js +++ b/src/color-middleware.js @@ -163,6 +163,8 @@ const htmlColors = { 'yellowgreen': '#9ACD32' } +const htmlColorKeys = Object.keys(htmlColors) + /** * Converts a color string to a Color. * @@ -253,7 +255,7 @@ const rgb = str => str.startsWith('rgb(') * @example * html('limegreen') */ -const html = str => Object.keys(htmlColors).indexOf(str) !== -1 +const html = str => htmlColorKeys.indexOf(str) !== -1 /** * Converts a hex string to a Color. diff --git a/src/frame.js b/src/frame.js index eeb5d5c..c8f9520 100644 --- a/src/frame.js +++ b/src/frame.js @@ -248,11 +248,7 @@ const frame = (timeline, at) => { const shapePosition = (timeline.state.position - start) / (finish - start) - return frameShapeFromShape({ - shape, - position: shapePosition, - middleware: timeline.middleware - }) + return frameShapeFromShape(shape, shapePosition, timeline.middleware) }) } @@ -306,19 +302,18 @@ const frameShapeFromPlainShapeObject = ({ shapes: childPlainShapeObjects, ...pla /** * Creates a FrameShape from a Shape given the Position. * - * @param {Object} opts - * @param {Middleware[]} opts.middleware - * @param {Position} opts.position - * @param {Shape} opts.shape + * @param {Shape} shape + * @param {Position} position + * @param {Middleware[]} middleware * * @returns {FrameShape} * * @example - * frameShapeFromShape({ position: 0.75, shape }) + * frameShapeFromShape(shape, 0.75, []) */ -const frameShapeFromShape = ({ middleware = [], position, shape }) => { - const fromIndex = shape.keyframes.reduce((currentFromIndex, { position: keyframePosition }, i) => ( - position > keyframePosition ? i : currentFromIndex +const frameShapeFromShape = (shape, position, middleware) => { + const fromIndex = shape.keyframes.reduce((currentFromIndex, keyframe, i) => ( + position > keyframe.position ? i : currentFromIndex ), 0) const toIndex = fromIndex + 1 @@ -442,7 +437,13 @@ const tween = (from, to, easing, position) => { throw new TypeError(errorMsg) } - return from.map((f, i) => (tween(f, to[ i ], easing, position))) + const arr = [] + + for (let i = 0, l = from.length; i < l; i++) { + arr.push(tween(from[ i ], to[ i ], easing, position)) + } + + return arr } else if (from !== null && typeof from === 'object') { if (to !== null && typeof to !== 'object') { throw new TypeError(errorMsg) @@ -450,9 +451,9 @@ const tween = (from, to, easing, position) => { const obj = {} - Object.keys(from).map(k => { + for (let k in from) { obj[ k ] = tween(from[ k ], to[ k ], easing, position) - }) + } return obj } else if (typeof from === 'number') { diff --git a/src/middleware.js b/src/middleware.js index db325ea..94bad04 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -23,15 +23,21 @@ const apply = (value, func) => { const v = func(value) if (Array.isArray(v)) { - return v.map(x => apply(x, func)) + const arr = [] + + for (let i = 0, l = v.length; i < l; i++) { + arr.push(apply(v[ i ], func)) + } + + return arr } if (v !== null && typeof v === 'object') { const obj = {} - Object.keys(v).map(k => { + for (let k in v) { obj[ k ] = apply(v[ k ], func) - }) + } return obj } @@ -50,9 +56,15 @@ const apply = (value, func) => { * @example * input({ foo: 1, bar: [ 2, 3 ] }, middleware) */ -const input = (value, middleware) => middleware.reduce((v, m) => ( - apply(v, m.input) -), value) +const input = (value, middleware) => { + let v = value + + for (let i = 0, l = middleware.length; i < l; i++) { + v = apply(v, middleware[ i ].input) + } + + return v +} /** * Runs each Middleware output function in reverse on a value. @@ -65,8 +77,14 @@ const input = (value, middleware) => middleware.reduce((v, m) => ( * @example * output({ foo: 1, bar: [ 2, 3 ] }, middleware) */ -const output = (value, middleware) => [ ...middleware ].reverse().reduce((v, m) => ( - apply(v, m.output) -), value) +const output = (value, middleware) => { + let v = value + + for (let i = middleware.length - 1; i >= 0; i--) { + v = apply(v, middleware[ i ].output) + } + + return v +} export { input, output }