Skip to content
This repository has been archived by the owner on Apr 14, 2020. It is now read-only.

Commit

Permalink
Merge pull request #89 from madou/perf
Browse files Browse the repository at this point in the history
chore: performance tweaks
  • Loading branch information
Madou authored Dec 29, 2018
2 parents 4b2e9cc + 29bde44 commit eda9f0e
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 240 deletions.
437 changes: 224 additions & 213 deletions packages/yubaba/src/Baba/index.tsx

Large diffs are not rendered by default.

142 changes: 142 additions & 0 deletions packages/yubaba/src/Baba/stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import Baba from './index';
import Noop from '../animations/Noop';

interface BabaProfilerProps {
iterations: number;
}

interface BabaProfilerState {
start: boolean;
profiling: boolean;
finished: boolean;
}

class BabaProfiler extends React.Component<BabaProfilerProps, BabaProfilerState> {
state: BabaProfilerState = BabaProfiler.getDefaultState();

curStart: number = -1;

curEnd: number = -1;

results: number[] = [];

iteration: number = 1;

onNextIteration = () => {
this.iteration += 1;

this.setState(
{
start: false,
},
() => {
if (this.iteration < this.props.iterations) {
this.curEnd = Date.now();
this.results.push(this.curEnd - this.curStart);
this.curStart = Date.now();

this.setState({
start: true,
});
} else {
this.curEnd = Date.now();
this.results.push(this.curEnd - this.curStart);

this.setState({
finished: true,
});
}
}
);
};

start = () => {
this.curStart = Date.now();

this.setState(
{
profiling: true,
},
() => {
this.setState({
start: true,
});
}
);
};

reset = () => {
this.curStart = -1;
this.curEnd = -1;
this.results = [];
this.iteration = 1;
this.setState(BabaProfiler.getDefaultState(), this.start);
};

static getDefaultState() {
return {
start: false,
profiling: false,
finished: false,
};
}

getAverage() {
return Math.ceil(this.results.reduce((val, total) => val + total, 0) / this.results.length);
}

render() {
if (this.state.finished) {
return (
<React.Fragment>
{`avg: ${this.getAverage()}ms`}
<button type="button" onClick={this.reset}>
reset
</button>
</React.Fragment>
);
}

if (!this.state.profiling) {
return (
<button type="button" onClick={this.start}>
start
</button>
);
}

return (
<div>
{!this.state.start ? (
<Baba name="profiler">
<Noop>
{baba => (
<div {...baba}>
<span>{this.iteration}</span>
</div>
)}
</Noop>
</Baba>
) : (
<div>
<Baba name="profiler" onFinish={this.onNextIteration}>
{baba => (
<div {...baba}>
<span>{this.iteration}</span>
</div>
)}
</Baba>
</div>
)}
</div>
);
}
}

storiesOf('yubaba/Baba', module)
.add('profiler (1)', () => <BabaProfiler iterations={1} />)
.add('profiler (10)', () => <BabaProfiler iterations={10} />)
.add('profiler (100)', () => <BabaProfiler iterations={100} />)
.add('profiler (1000)', () => <BabaProfiler iterations={1000} />);
6 changes: 3 additions & 3 deletions packages/yubaba/src/Collector/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { GetElementSizeLocationReturnValue } from '../lib/dom';
import { ElementBoundingBox } from '../lib/dom';

export interface TargetProps {
style: InlineStyles;
Expand Down Expand Up @@ -84,9 +84,9 @@ export interface InlineStyles {
*/
export interface ElementData {
element: HTMLElement;
elementBoundingBox: GetElementSizeLocationReturnValue;
elementBoundingBox: ElementBoundingBox;
focalTargetElement: HTMLElement | null | undefined;
focalTargetElementBoundingBox: GetElementSizeLocationReturnValue | undefined;
focalTargetElementBoundingBox: ElementBoundingBox | undefined;
render: CollectorChildrenAsFunction;
}

Expand Down
6 changes: 4 additions & 2 deletions packages/yubaba/src/animations/CircleExpand/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { calculateHypotenuse } from '../../lib/math';
import {
calculateWindowCentre,
calculateElementCenterInViewport,
recalculateLocationFromScroll,
recalculateElementBoundingBoxFromScroll,
} from '../../lib/dom';
import SimpleKeyframe from '../SimpleKeyframe';
import { standard, accelerate } from '../../lib/curves';
Expand Down Expand Up @@ -51,7 +51,9 @@ export default class CircleExpand extends React.Component<CircleExpandProps> {
const { duration, background, zIndex } = this.props;

// Scroll could have changed between unmount and this prepare step, let's recalculate just in case.
const fromTargetSizeLocation = recalculateLocationFromScroll(data.origin.elementBoundingBox);
const fromTargetSizeLocation = recalculateElementBoundingBoxFromScroll(
data.origin.elementBoundingBox
);
const minSize = Math.min(fromTargetSizeLocation.size.width, fromTargetSizeLocation.size.height);
const fromTargetHypotenuse = calculateHypotenuse(fromTargetSizeLocation.size);
const fromTargetCenterInViewport = calculateElementCenterInViewport(fromTargetSizeLocation);
Expand Down
6 changes: 4 additions & 2 deletions packages/yubaba/src/animations/ConcealMove/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Collector, {
CollectorActions,
AnimationData,
} from '../../Collector';
import { recalculateLocationFromScroll } from '../../lib/dom';
import { recalculateElementBoundingBoxFromScroll } from '../../lib/dom';
import noop from '../../lib/noop';
import { standard } from '../../lib/curves';
import { zIndexStack } from '../../lib/style';
Expand Down Expand Up @@ -53,7 +53,9 @@ targetElement was missing.`);

const { duration, timingFunction, zIndex } = this.props;
// Scroll could have changed between unmount and this prepare step.
const fromTargetSizeLocation = recalculateLocationFromScroll(data.origin.elementBoundingBox);
const fromTargetSizeLocation = recalculateElementBoundingBoxFromScroll(
data.origin.elementBoundingBox
);

return data.origin.render({
ref: noop,
Expand Down
6 changes: 4 additions & 2 deletions packages/yubaba/src/animations/FadeMove/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Collector, {
AnimationData,
} from '../../Collector';
import * as math from '../../lib/math';
import { recalculateLocationFromScroll } from '../../lib/dom';
import { recalculateElementBoundingBoxFromScroll } from '../../lib/dom';
import noop from '../../lib/noop';
import { standard } from '../../lib/curves';
import { zIndexStack } from '../../lib/style';
Expand Down Expand Up @@ -51,7 +51,9 @@ export default class FadeMove extends React.Component<FadeMoveProps> {
const { timingFunction, duration, zIndex } = this.props;
// Scroll could have changed between unmount and this prepare step, let's recalculate
// just in case.
const fromTargetSizeLocation = recalculateLocationFromScroll(data.origin.elementBoundingBox);
const fromTargetSizeLocation = recalculateElementBoundingBoxFromScroll(
data.origin.elementBoundingBox
);
const fromEndXOffset =
data.destination.elementBoundingBox.location.left - fromTargetSizeLocation.location.left;
const fromEndYOffset =
Expand Down
4 changes: 2 additions & 2 deletions packages/yubaba/src/animations/Move/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Collector, {
CollectorActions,
} from '../../Collector';
import * as math from '../../lib/math';
import { recalculateLocationFromScroll } from '../../lib/dom';
import { recalculateElementBoundingBoxFromScroll } from '../../lib/dom';
import { standard } from '../../lib/curves';
import { combine, zIndexStack } from '../../lib/style';

Expand Down Expand Up @@ -75,7 +75,7 @@ targetElement was missing.`);
}

// Scroll could have changed between unmount and this prepare step.
const originTarget = recalculateLocationFromScroll(data.origin.elementBoundingBox);
const originTarget = recalculateElementBoundingBoxFromScroll(data.origin.elementBoundingBox);
const destinationTarget =
useFocalTarget && data.destination.focalTargetElementBoundingBox
? data.destination.focalTargetElementBoundingBox
Expand Down
2 changes: 1 addition & 1 deletion packages/yubaba/src/animations/Noop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface NoopProps extends CollectorChildrenProps {
*/
export default class Noop extends React.Component<NoopProps> {
static defaultProps = {
duration: 1,
duration: 0,
};

render() {
Expand Down
30 changes: 15 additions & 15 deletions packages/yubaba/src/lib/dom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ export function getDocumentScroll() {
/**
* @hidden
*/
export interface GetElementSizeLocationOptions {
export interface ElementBoundingBoxOpts {
useOffsetSize?: boolean;
}

/**
* @hidden
*/
export interface GetElementSizeLocationReturnValue {
export interface ElementBoundingBox {
size: {
width: number;
height: number;
Expand All @@ -49,8 +49,8 @@ export interface GetElementSizeLocationReturnValue {
*/
export function getElementBoundingBox(
element: HTMLElement,
options: GetElementSizeLocationOptions = {}
): GetElementSizeLocationReturnValue {
options: ElementBoundingBoxOpts = {}
): ElementBoundingBox {
const rect = element.getBoundingClientRect();
const { scrollLeft, scrollTop } = getDocumentScroll();
const topOffset = (rect.height - element.offsetHeight) / 2;
Expand All @@ -76,10 +76,10 @@ export function getElementBoundingBox(
/**
* @hidden
*/
export function calculateElementCenterInViewport(sizeLocation: GetElementSizeLocationReturnValue) {
export function calculateElementCenterInViewport(elementBoundingBox: ElementBoundingBox) {
return {
top: sizeLocation.location.top + Math.ceil(sizeLocation.size.width / 2),
left: sizeLocation.location.left - Math.ceil(sizeLocation.size.height / 2),
top: elementBoundingBox.location.top + Math.ceil(elementBoundingBox.size.width / 2),
left: elementBoundingBox.location.left - Math.ceil(elementBoundingBox.size.height / 2),
};
}

Expand All @@ -96,18 +96,18 @@ export function calculateWindowCentre() {
/**
* @hidden
*/
export function recalculateLocationFromScroll(
sizeLocation: GetElementSizeLocationReturnValue
): GetElementSizeLocationReturnValue {
export function recalculateElementBoundingBoxFromScroll(
elementBoundingBox: ElementBoundingBox
): ElementBoundingBox {
const { scrollTop, scrollLeft } = getDocumentScroll();
const scrollTopDiff = scrollTop - sizeLocation.raw.scrollTop;
const scrollLeftDiff = scrollLeft - sizeLocation.raw.scrollLeft;
const scrollTopDiff = scrollTop - elementBoundingBox.raw.scrollTop;
const scrollLeftDiff = scrollLeft - elementBoundingBox.raw.scrollLeft;

return {
...sizeLocation,
...elementBoundingBox,
location: {
top: sizeLocation.location.top + scrollTopDiff,
left: sizeLocation.location.left + scrollLeftDiff,
top: elementBoundingBox.location.top + scrollTopDiff,
left: elementBoundingBox.location.left + scrollLeftDiff,
},
};
}
1 change: 1 addition & 0 deletions test/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ require('jest-enzyme');

enzyme.configure({ adapter: new Adapter() });
expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));
window.requestAnimationFrame = cb => cb();

0 comments on commit eda9f0e

Please sign in to comment.