diff --git a/packages/benchmarks/README.md b/packages/benchmarks/README.md index 149e0eb79..d162e7e2c 100644 --- a/packages/benchmarks/README.md +++ b/packages/benchmarks/README.md @@ -6,41 +6,50 @@ To run these benchmarks: yarn benchmark ``` -Append `?fastest` to the URL to include the fastest "other libraries", and -`?all` to include all the "other libraries". +To run benchmarks for individual implementations append `?,` to the +URL, e.g., `?css-modules,react-native-web`. ## Notes +These benchmarks are crude approximations of extreme cases that libraries may +encounter. The deep and wide tree cases look at the performance of mounting and +rendering large trees of styled elements. The Triangle cases looks at the +performance of repeated style updates to a large mounted tree. Some libraries +must inject new styles for each "dynamic style", whereas others may not. +Libraries without support for dynamic styles (i.e., they rely on user-authored +inline styles) do not include the `SierpinskiTriangle` benchmark. + The components used in the render benchmarks are simple enough to be -implemented by multiple UI or style libraries. The implementations are not -equivalent in functionality. For example, the "React Native for Web" benchmark includes a -complete `View` implementation and the `StyleSheet` also converts React Native -styles to DOM styles, has deterministic resolution, and supports RTL layout. +implemented by multiple UI or style libraries. The benchmark implementations +and the features of the style libraries are _only approximately equivalent in +functionality_. ## Results Typical render timings*: mean ± two standard deviations. -| Implementation | Deep tree (ms) | Wide tree (ms) | Tweets (ms) | +| Implementation | Deep tree (ms) | Wide tree (ms) | Triangle (ms) | | :--- | ---: | ---: | ---: | -| `css-modules` | `80.47` `±25.13` | `144.87` `±32.70` | | -| `react-native-web@0.2.2` | `88.68` `±28.78` | `178.17` `±39.90` | `13.78` `±2.90ms` | +| `react-native-web@0.2.2` | `89.67` `±28.51` | `167.46` `±27.03` | `65.40` `±19.50` | +| `css-modules` | `77.42` `±45.50` | `141.44` `±33.96` | - | +| `inline-styles` | `236.25` `±95.57` | `477.01` `±88.30` | `40.95` `±23.53` | Other libraries -| Implementation | Deep tree (ms) | Wide tree (ms) | +| Implementation | Deep tree (ms) | Wide tree (ms) | Triangle (ms) | | :--- | ---: | ---: | -| `styletron@3.0.0-rc.5` | `79.41` `±27.49` | `152.95` `±29.46` | -| `aphrodite@1.2.5` | `85.13` `±25.39` | `162.87` `±25.91` | -| `glamor@2.20.40` | `109.92` `±29.88` | `193.01` `±32.03` | -| `react-jss@8.2.0` | `134.28` `±49.00` | `278.78` `±50.39` | -| `emotion@8.0.12` | `139.08` `±46.18` | `253.45` `±52.69` | -| `styled-components@2.3.2` | `194.43` `±46.28` | `404.86` `±56.59` | -| `reactxp@0.46.6` | `219.46` `±57.24` | `424.18` `±76.10` | -| `radium@0.19.6` | `359.32` `±90.27` | `795.91` `±88.93` | +| `styletron@3.0.0-rc.5` | `83.53` `±33.55` | `153.12` `±39.13` | `56.47` `±24.22` | +| `aphrodite@1.2.5` | `88.23` `±31.22` | `164.03` `±34.70` | - | +| `glamor@2.20.40` | `110.09` `±34.20` | `182.06` `±50.39` | ‡ | +| `emotion@8.0.12` | `103.44` `±32.12` | `204.45` `±41.00` | `110.28` `±26.94` | +| `react-jss@8.2.0` | `136.17` `±59.23` | `270.51` `±69.20` | - | +| `styled-components@2.3.2` | `217.57` `±51.90` | `437.57` `±65.74` | `76.99` `±41.79` | +| `reactxp@0.46.6` | `240.88` `±79.82` | `467.32` `±74.42` | `70.95` `±32.90`| +| `radium@0.19.6` | `400.19` `±94.58` | `816.59` `±91.10` | `71.13` `±27.22` | These results indicate that render times when using `react-native-web`, `css-modules`, `aphrodite`, and `styletron` are roughly equivalent and significantly faster than alternatives. *MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3. Google Chrome 62. +‡Glamor essentially crashes diff --git a/packages/benchmarks/index.js b/packages/benchmarks/index.js deleted file mode 100644 index 07a0783ae..000000000 --- a/packages/benchmarks/index.js +++ /dev/null @@ -1,63 +0,0 @@ -import aphrodite from './src/aphrodite'; -import cssModules from './src/css-modules'; -import emotion from './src/emotion'; -import glamor from './src/glamor'; -import jss from './src/jss'; -import radium from './src/radium'; -import reactNative from './src/react-native'; -import styledComponents from './src/styled-components'; -import styletron from './src/styletron'; -import xp from './src/reactxp'; - -import renderDeepTree from './tests/renderDeepTree'; -import renderTweet from './tests/renderTweet'; -import renderWideTree from './tests/renderWideTree'; - -const testAll = window.location.search === '?all'; -const testFastest = window.location.search === '?fastest'; - -const coreTests = [ - () => renderTweet('react-native-web', reactNative), - - () => renderDeepTree('css-modules', cssModules), - () => renderWideTree('css-modules', cssModules), - () => renderDeepTree('react-native-web', reactNative), - () => renderWideTree('react-native-web', reactNative) -]; - -const fastestTests = [ - () => renderDeepTree('styletron', styletron), - () => renderWideTree('styletron', styletron), - () => renderDeepTree('aphrodite', aphrodite), - () => renderWideTree('aphrodite', aphrodite) -]; - -/** - * Optionally run tests using other libraries - */ -const restTests = [ - () => renderDeepTree('glamor', glamor), - () => renderWideTree('glamor', glamor), - () => renderDeepTree('react-jss', jss), - () => renderWideTree('react-jss', jss), - () => renderDeepTree('emotion', emotion), - () => renderWideTree('emotion', emotion), - () => renderDeepTree('styled-components', styledComponents), - () => renderWideTree('styled-components', styledComponents), - () => renderDeepTree('reactxp', xp), - () => renderWideTree('reactxp', xp), - () => renderDeepTree('radium', radium), - () => renderWideTree('radium', radium) -]; - -const tests = [...coreTests]; -if (testFastest) { - tests.push(...fastestTests); -} -if (testAll) { - tests.push(...fastestTests); - tests.push(...restTests); -} - -// run benchmarks -tests.reduce((promise, test) => promise.then(test()), Promise.resolve()); diff --git a/packages/benchmarks/package.json b/packages/benchmarks/package.json index 52835828a..9c3e3df00 100644 --- a/packages/benchmarks/package.json +++ b/packages/benchmarks/package.json @@ -7,7 +7,9 @@ }, "dependencies": { "aphrodite": "^1.2.5", + "babel-polyfill": "^6.26.0", "classnames": "^2.2.5", + "d3-scale-chromatic": "^1.1.1", "emotion": "^8.0.12", "glamor": "^2.20.40", "marky": "^1.2.0", diff --git a/packages/benchmarks/src/aphrodite.js b/packages/benchmarks/src/aphrodite.js deleted file mode 100644 index e09522ee2..000000000 --- a/packages/benchmarks/src/aphrodite.js +++ /dev/null @@ -1,7 +0,0 @@ -import Box from './components/Box/aphrodite'; -import View from './components/View/aphrodite'; - -export default { - Box, - View -}; diff --git a/packages/benchmarks/benchmark.js b/packages/benchmarks/src/benchmark.js similarity index 71% rename from packages/benchmarks/benchmark.js rename to packages/benchmarks/src/benchmark.js index fc2e9368c..41316cbe7 100644 --- a/packages/benchmarks/benchmark.js +++ b/packages/benchmarks/src/benchmark.js @@ -38,30 +38,31 @@ const standardDeviation = values => { return Math.sqrt(meanSquareDiff); }; +export const log = (name, description, durations) => { + const stdDev = standardDeviation(durations); + const formattedMean = fmt(mean(durations)); + const formattedMedian = fmt(median(durations)); + const formattedStdDev = fmt(stdDev); + + console.groupCollapsed(`${name}\n${formattedMean} ±${fmt(2 * stdDev)}`); + description && console.log(description); + console.log(`Median: ${formattedMedian}`); + console.log(`Mean: ${formattedMean}`); + console.log(`Standard deviation: ${formattedStdDev}`); + console.log(durations); + console.groupEnd(); +}; + const benchmark = ({ name, description, setup, teardown, task, runs }) => { return new Promise(resolve => { const durations = []; let i = 0; setup(); - const first = measure('first', task); teardown(); const done = () => { - const stdDev = standardDeviation(durations); - const formattedFirst = fmt(first); - const formattedMean = fmt(mean(durations)); - const formattedMedian = fmt(median(durations)); - const formattedStdDev = fmt(stdDev); - - console.groupCollapsed(`${name}\n${formattedMean} ±${fmt(2 * stdDev)}`); - description && console.log(description); - console.log(`First: ${formattedFirst}`); - console.log(`Median: ${formattedMedian}`); - console.log(`Mean: ${formattedMean}`); - console.log(`Standard deviation: ${formattedStdDev}`); - console.log(durations); - console.groupEnd(); + log(name, description, durations); resolve(); }; diff --git a/packages/benchmarks/src/components/NestedTree/index.js b/packages/benchmarks/src/cases/NestedTree.js similarity index 100% rename from packages/benchmarks/src/components/NestedTree/index.js rename to packages/benchmarks/src/cases/NestedTree.js diff --git a/packages/benchmarks/src/cases/SierpinskiTriangle.js b/packages/benchmarks/src/cases/SierpinskiTriangle.js new file mode 100644 index 000000000..386e8545b --- /dev/null +++ b/packages/benchmarks/src/cases/SierpinskiTriangle.js @@ -0,0 +1,84 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { interpolatePurples, interpolateBuPu, interpolateRdPu } from 'd3-scale-chromatic'; + +const targetSize = 25; + +class SierpinskiTriangle extends React.Component { + static propTypes = { + Dot: PropTypes.node, + depth: PropTypes.number, + renderCount: PropTypes.number, + s: PropTypes.number, + x: PropTypes.number, + y: PropTypes.number + }; + + static defaultProps = { + depth: 0, + renderCount: 0 + }; + + render() { + const { x, y, depth, renderCount, Dot } = this.props; + let { s } = this.props; + + if (s <= targetSize) { + let fn; + switch (depth) { + case 1: + fn = interpolatePurples; + break; + case 2: + fn = interpolateBuPu; + break; + case 3: + default: + fn = interpolateRdPu; + } + + return ( + + ); + } + + s /= 2; + + return [ + , + , + + ]; + } +} + +export default SierpinskiTriangle; diff --git a/packages/benchmarks/tests/renderDeepTree.js b/packages/benchmarks/src/cases/renderDeepTree.js similarity index 78% rename from packages/benchmarks/tests/renderDeepTree.js rename to packages/benchmarks/src/cases/renderDeepTree.js index 60fdc8d19..ca9e8b969 100644 --- a/packages/benchmarks/tests/renderDeepTree.js +++ b/packages/benchmarks/src/cases/renderDeepTree.js @@ -1,10 +1,10 @@ import createRenderBenchmark from '../createRenderBenchmark'; -import NestedTree from '../src/components/NestedTree'; +import NestedTree from './NestedTree'; import React from 'react'; const renderDeepTree = (label, components) => createRenderBenchmark({ - name: `Deep tree [${label}]`, + name: `[${label}] Deep tree`, runs: 20, getElement() { return ; diff --git a/packages/benchmarks/src/cases/renderSierpinskiTriangle.js b/packages/benchmarks/src/cases/renderSierpinskiTriangle.js new file mode 100644 index 000000000..15763f094 --- /dev/null +++ b/packages/benchmarks/src/cases/renderSierpinskiTriangle.js @@ -0,0 +1,112 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import SierpinskiTriangle from './SierpinskiTriangle'; +import { log } from '../benchmark'; + +const node = document.querySelector('.root'); + +let runs = 20; + +class Speedometer extends React.Component { + /* necessary for reactxp to work without errors */ + static childContextTypes = { + focusManager: PropTypes.object + }; + getChildContext() { + return { + focusManager: { + addFocusableComponent() {}, + removeFocusableComponent() {}, + restrictFocusWithin() {}, + removeFocusRestriction() {}, + limitFocusWithin() {}, + removeFocusLimitation() {} + } + }; + } + + static propTypes = { + Dot: PropTypes.node.isRequired, + description: PropTypes.string, + name: PropTypes.string.isRequired, + onComplete: PropTypes.node.isRequired + }; + + state = { renderCount: -1 }; + + async componentDidMount() { + const durations = []; + + while ((runs -= 1)) { + const prev = window.performance.now(); + await new Promise(resolve => { + this.raf = window.requestAnimationFrame(() => { + this.setState({ renderCount: this.state.renderCount + 1 }, () => { + const now = window.performance.now(); + durations.push(now - prev); + resolve(); + }); + }); + }); + } + + const { description, name } = this.props; + log(name, description, durations); + + runs = 20; + this.props.onComplete(); + } + + componentWillUnmount() { + window.cancelAnimationFrame(this.raf); + } + + render() { + return ( +
+ +
+ ); + } +} + +const styles = { + wrapper: { + position: 'absolute', + transformOrigin: '0 0', + left: '50%', + top: '50%', + width: '10px', + height: '10px', + backgroundColor: '#eee', + transform: 'scale(0.33)' + } +}; + +const renderSierpinskiTriangle = (name, { Dot }) => () => { + return new Promise(resolve => { + /* eslint-disable react/jsx-no-bind */ + ReactDOM.render( + { + ReactDOM.unmountComponentAtNode(node); + resolve(); + }} + />, + node + ); + /* eslint-enable react/jsx-no-bind */ + }); +}; + +export default renderSierpinskiTriangle; diff --git a/packages/benchmarks/tests/renderTweet.js b/packages/benchmarks/src/cases/renderTweet.js similarity index 95% rename from packages/benchmarks/tests/renderTweet.js rename to packages/benchmarks/src/cases/renderTweet.js index 3243430a8..2f2e4dff9 100644 --- a/packages/benchmarks/tests/renderTweet.js +++ b/packages/benchmarks/src/cases/renderTweet.js @@ -1,5 +1,4 @@ import createRenderBenchmark from '../createRenderBenchmark'; -import Tweet from '../src/components/Tweet'; import React from 'react'; const tweet1 = { @@ -96,9 +95,9 @@ const tweet2 = { } }; -const renderTweet = label => +const renderTweet = (label, { Tweet }) => createRenderBenchmark({ - name: `Tweet [${label}]`, + name: `[${label}] Tweet`, runs: 10, getElement() { return ( diff --git a/packages/benchmarks/tests/renderWideTree.js b/packages/benchmarks/src/cases/renderWideTree.js similarity index 78% rename from packages/benchmarks/tests/renderWideTree.js rename to packages/benchmarks/src/cases/renderWideTree.js index 948585ca6..15c1740f5 100644 --- a/packages/benchmarks/tests/renderWideTree.js +++ b/packages/benchmarks/src/cases/renderWideTree.js @@ -1,10 +1,10 @@ import createRenderBenchmark from '../createRenderBenchmark'; -import NestedTree from '../src/components/NestedTree'; +import NestedTree from './NestedTree'; import React from 'react'; const renderWideTree = (label, components) => createRenderBenchmark({ - name: `Wide tree [${label}]`, + name: `[${label}] Wide tree`, runs: 20, getElement() { return ; diff --git a/packages/benchmarks/createRenderBenchmark.js b/packages/benchmarks/src/createRenderBenchmark.js similarity index 100% rename from packages/benchmarks/createRenderBenchmark.js rename to packages/benchmarks/src/createRenderBenchmark.js diff --git a/packages/benchmarks/src/css-modules.js b/packages/benchmarks/src/css-modules.js deleted file mode 100644 index fc62f9ada..000000000 --- a/packages/benchmarks/src/css-modules.js +++ /dev/null @@ -1,9 +0,0 @@ -import Box from './components/Box/css-modules'; -import View from './components/View/css-modules'; - -const api = { - Box, - View -}; - -export default api; diff --git a/packages/benchmarks/src/emotion.js b/packages/benchmarks/src/emotion.js deleted file mode 100644 index 1b4a6a333..000000000 --- a/packages/benchmarks/src/emotion.js +++ /dev/null @@ -1,7 +0,0 @@ -import Box from './components/Box/emotion'; -import View from './components/View/emotion'; - -export default { - Box, - View -}; diff --git a/packages/benchmarks/src/glamor.js b/packages/benchmarks/src/glamor.js deleted file mode 100644 index bef27a117..000000000 --- a/packages/benchmarks/src/glamor.js +++ /dev/null @@ -1,7 +0,0 @@ -import Box from './components/Box/glamor'; -import View from './components/View/glamor'; - -export default { - Box, - View -}; diff --git a/packages/benchmarks/src/components/Box/aphrodite.js b/packages/benchmarks/src/implementations/aphrodite/Box.js similarity index 95% rename from packages/benchmarks/src/components/Box/aphrodite.js rename to packages/benchmarks/src/implementations/aphrodite/Box.js index 777ec0ea6..2759fd1bf 100644 --- a/packages/benchmarks/src/components/Box/aphrodite.js +++ b/packages/benchmarks/src/implementations/aphrodite/Box.js @@ -1,6 +1,6 @@ /* eslint-disable react/prop-types */ import React from 'react'; -import View from '../View/aphrodite'; +import View from './View'; import { StyleSheet } from 'aphrodite'; const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( diff --git a/packages/benchmarks/src/components/View/aphrodite.js b/packages/benchmarks/src/implementations/aphrodite/View.js similarity index 100% rename from packages/benchmarks/src/components/View/aphrodite.js rename to packages/benchmarks/src/implementations/aphrodite/View.js diff --git a/packages/benchmarks/src/implementations/aphrodite/index.js b/packages/benchmarks/src/implementations/aphrodite/index.js new file mode 100644 index 000000000..0ca161ab5 --- /dev/null +++ b/packages/benchmarks/src/implementations/aphrodite/index.js @@ -0,0 +1,7 @@ +import Box from './Box'; +import View from './View'; + +export default { + Box, + View +}; diff --git a/packages/benchmarks/src/components/Box/css-modules.js b/packages/benchmarks/src/implementations/css-modules/Box.js similarity index 84% rename from packages/benchmarks/src/components/Box/css-modules.js rename to packages/benchmarks/src/implementations/css-modules/Box.js index 04ad8a0b5..5671bfaf2 100644 --- a/packages/benchmarks/src/components/Box/css-modules.js +++ b/packages/benchmarks/src/implementations/css-modules/Box.js @@ -1,8 +1,8 @@ /* eslint-disable react/prop-types */ import classnames from 'classnames'; import React from 'react'; -import View from '../View/css-modules'; -import styles from './styles.css'; +import View from './View'; +import styles from './box-styles.css'; const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( ( ( +
+ {children} +
+); + +const styles = { + root: { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + } +}; + +export default Dot; diff --git a/packages/benchmarks/src/components/View/emotion.js b/packages/benchmarks/src/implementations/emotion/View.js similarity index 88% rename from packages/benchmarks/src/components/View/emotion.js rename to packages/benchmarks/src/implementations/emotion/View.js index 8c103f2ab..798974636 100644 --- a/packages/benchmarks/src/components/View/emotion.js +++ b/packages/benchmarks/src/implementations/emotion/View.js @@ -5,7 +5,7 @@ import React from 'react'; class View extends React.Component { render() { const { style, ...other } = this.props; - return
; + return
; } } diff --git a/packages/benchmarks/src/implementations/emotion/index.js b/packages/benchmarks/src/implementations/emotion/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/emotion/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/components/Box/emotion.js b/packages/benchmarks/src/implementations/glamor/Box.js similarity index 95% rename from packages/benchmarks/src/components/Box/emotion.js rename to packages/benchmarks/src/implementations/glamor/Box.js index 3cfacd645..dd33fded7 100644 --- a/packages/benchmarks/src/components/Box/emotion.js +++ b/packages/benchmarks/src/implementations/glamor/Box.js @@ -1,6 +1,6 @@ /* eslint-disable react/prop-types */ import React from 'react'; -import View from '../View/emotion'; +import View from './View'; const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( ( +
+ {children} +
+); + +const styles = { + root: { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + } +}; + +export default Dot; diff --git a/packages/benchmarks/src/components/View/glamor.js b/packages/benchmarks/src/implementations/glamor/View.js similarity index 100% rename from packages/benchmarks/src/components/View/glamor.js rename to packages/benchmarks/src/implementations/glamor/View.js diff --git a/packages/benchmarks/src/implementations/glamor/index.js b/packages/benchmarks/src/implementations/glamor/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/glamor/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/implementations/inline-styles/Box.js b/packages/benchmarks/src/implementations/inline-styles/Box.js new file mode 100644 index 000000000..99a1ef2c6 --- /dev/null +++ b/packages/benchmarks/src/implementations/inline-styles/Box.js @@ -0,0 +1,48 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; +import View from './View'; + +const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( + +); + +const styles = { + outer: { + padding: 4 + }, + row: { + flexDirection: 'row' + }, + color0: { + backgroundColor: '#222' + }, + color1: { + backgroundColor: '#666' + }, + color2: { + backgroundColor: '#999' + }, + color3: { + backgroundColor: 'blue' + }, + color4: { + backgroundColor: 'orange' + }, + color5: { + backgroundColor: 'red' + }, + fixed: { + width: 20, + height: 20 + } +}; + +export default Box; diff --git a/packages/benchmarks/src/implementations/inline-styles/Dot.js b/packages/benchmarks/src/implementations/inline-styles/Dot.js new file mode 100644 index 000000000..be0dee353 --- /dev/null +++ b/packages/benchmarks/src/implementations/inline-styles/Dot.js @@ -0,0 +1,34 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; + +const Dot = ({ size, x, y, children, color }) => ( +
+ {children} +
+); + +const styles = { + root: { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + } +}; + +export default Dot; diff --git a/packages/benchmarks/src/implementations/inline-styles/View.js b/packages/benchmarks/src/implementations/inline-styles/View.js new file mode 100644 index 000000000..6bd469e04 --- /dev/null +++ b/packages/benchmarks/src/implementations/inline-styles/View.js @@ -0,0 +1,36 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; + +const compose = (s1, s2) => { + if (s1 && s2) { + return { ...s1, ...s2 }; + } else { + return s1 || s2; + } +}; + +class View extends React.Component { + render() { + const { style, ...other } = this.props; + return
; + } +} + +const viewStyle = { + alignItems: 'stretch', + borderWidth: 0, + borderStyle: 'solid', + boxSizing: 'border-box', + display: 'flex', + flexBasis: 'auto', + flexDirection: 'column', + flexShrink: 0, + margin: 0, + padding: 0, + position: 'relative', + // fix flexbox bugs + minHeight: 0, + minWidth: 0 +}; + +export default View; diff --git a/packages/benchmarks/src/implementations/inline-styles/index.js b/packages/benchmarks/src/implementations/inline-styles/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/inline-styles/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/components/Box/jss.js b/packages/benchmarks/src/implementations/jss/Box.js similarity index 96% rename from packages/benchmarks/src/components/Box/jss.js rename to packages/benchmarks/src/implementations/jss/Box.js index f7f686004..251916723 100644 --- a/packages/benchmarks/src/components/Box/jss.js +++ b/packages/benchmarks/src/implementations/jss/Box.js @@ -2,7 +2,7 @@ import classnames from 'classnames'; import injectSheet from 'react-jss'; import React from 'react'; -import View from '../View/jss'; +import View from './View'; const Box = ({ classes, color, fixed = false, layout = 'column', outer = false, ...other }) => ( ( ( +
+ {children} +
+); + +const styles = { + root: { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + } +}; + +export default Radium(Dot); diff --git a/packages/benchmarks/src/components/View/radium.js b/packages/benchmarks/src/implementations/radium/View.js similarity index 100% rename from packages/benchmarks/src/components/View/radium.js rename to packages/benchmarks/src/implementations/radium/View.js diff --git a/packages/benchmarks/src/implementations/radium/index.js b/packages/benchmarks/src/implementations/radium/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/radium/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/components/Box/react-native.js b/packages/benchmarks/src/implementations/react-native-web/Box.js similarity index 100% rename from packages/benchmarks/src/components/Box/react-native.js rename to packages/benchmarks/src/implementations/react-native-web/Box.js diff --git a/packages/benchmarks/src/implementations/react-native-web/Dot.js b/packages/benchmarks/src/implementations/react-native-web/Dot.js new file mode 100644 index 000000000..bfa47fef3 --- /dev/null +++ b/packages/benchmarks/src/implementations/react-native-web/Dot.js @@ -0,0 +1,32 @@ +/* eslint-disable react/prop-types */ +import { createElement, StyleSheet } from 'react-native'; + +const Dot = ({ size, x, y, children, color }) => + createElement('div', { + children, + style: [ + styles.root, + { + borderBottomColor: color, + borderRightWidth: size / 2, + borderBottomWidth: size / 2, + borderLeftWidth: size / 2, + left: x, + top: y + } + ] + }); + +const styles = StyleSheet.create({ + root: { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + } +}); + +export default Dot; diff --git a/packages/benchmarks/src/components/AppText/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/AppText.js similarity index 98% rename from packages/benchmarks/src/components/AppText/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/AppText.js index 5d5e3c232..eb208872c 100644 --- a/packages/benchmarks/src/components/AppText/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/AppText.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import theme from '../theme'; +import theme from './theme'; import React, { PureComponent } from 'react'; import { StyleSheet, Text } from 'react-native'; diff --git a/packages/benchmarks/src/components/AspectRatio/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/AspectRatio.js similarity index 89% rename from packages/benchmarks/src/components/AspectRatio/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/AspectRatio.js index deb09be55..4a170b0ff 100644 --- a/packages/benchmarks/src/components/AspectRatio/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/AspectRatio.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React, { PureComponent } from 'react'; -import { StyleSheet, View } from 'react-native'; +import { StyleSheet, View, ViewPropTypes } from 'react-native'; class AspectRatio extends PureComponent { static displayName = 'AspectRatio'; @@ -8,7 +8,7 @@ class AspectRatio extends PureComponent { static propTypes = { children: PropTypes.any, ratio: PropTypes.number, - style: PropTypes.object + style: ViewPropTypes.style }; static defaultProps = { diff --git a/packages/benchmarks/src/components/GridView/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/GridView.js similarity index 90% rename from packages/benchmarks/src/components/GridView/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/GridView.js index 63900244f..6460c6099 100644 --- a/packages/benchmarks/src/components/GridView/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/GridView.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; -import { StyleSheet, View } from 'react-native'; +import { StyleSheet, View, ViewPropTypes } from 'react-native'; import React, { Component } from 'react'; -import theme from '../theme'; +import theme from './theme'; class GridView extends Component { static displayName = 'GridView'; @@ -9,7 +9,7 @@ class GridView extends Component { static propTypes = { children: PropTypes.node, hasGap: PropTypes.bool, - style: PropTypes.object + style: ViewPropTypes.style }; render() { diff --git a/packages/benchmarks/src/components/Icons/DirectMessage.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/IconDirectMessage.js similarity index 100% rename from packages/benchmarks/src/components/Icons/DirectMessage.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/IconDirectMessage.js diff --git a/packages/benchmarks/src/components/Icons/Heart.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/IconHeart.js similarity index 100% rename from packages/benchmarks/src/components/Icons/Heart.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/IconHeart.js diff --git a/packages/benchmarks/src/components/Icons/Reply.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/IconReply.js similarity index 100% rename from packages/benchmarks/src/components/Icons/Reply.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/IconReply.js diff --git a/packages/benchmarks/src/components/Icons/Retweet.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/IconRetweet.js similarity index 100% rename from packages/benchmarks/src/components/Icons/Retweet.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/IconRetweet.js diff --git a/packages/benchmarks/src/components/TweetAction/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetAction.js similarity index 85% rename from packages/benchmarks/src/components/TweetAction/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/TweetAction.js index 8df762cac..4b7ab521e 100644 --- a/packages/benchmarks/src/components/TweetAction/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetAction.js @@ -1,11 +1,11 @@ -import IconReply from '../Icons/Reply'; -import IconHeart from '../Icons/Heart'; -import IconRetweet from '../Icons/Retweet'; -import IconDirectMessage from '../Icons/DirectMessage'; +import IconReply from './IconReply'; +import IconHeart from './IconHeart'; +import IconRetweet from './IconRetweet'; +import IconDirectMessage from './IconDirectMessage'; import PropTypes from 'prop-types'; import React from 'react'; -import theme from '../theme'; -import { Text, View, StyleSheet } from 'react-native'; +import theme from './theme'; +import { Text, View, ViewPropTypes, StyleSheet } from 'react-native'; const getIcon = (icon, highlighted) => { switch (icon) { @@ -30,7 +30,7 @@ export default class TweetAction extends React.Component { displayMode: PropTypes.oneOf(['like', 'reply', 'retweet', 'directMessage']), highlighted: PropTypes.bool, onPress: PropTypes.func, - style: PropTypes.object + style: ViewPropTypes.style }; render() { diff --git a/packages/benchmarks/src/components/TweetActionsBar/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetActionsBar.js similarity index 89% rename from packages/benchmarks/src/components/TweetActionsBar/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/TweetActionsBar.js index 19f8b2c91..b91caca49 100644 --- a/packages/benchmarks/src/components/TweetActionsBar/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetActionsBar.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; -import TweetAction from '../TweetAction'; -import { View, StyleSheet } from 'react-native'; +import TweetAction from './TweetAction'; +import { View, ViewPropTypes, StyleSheet } from 'react-native'; import React, { PureComponent } from 'react'; const actionNames = ['reply', 'retweet', 'like', 'directMessage']; @@ -16,7 +16,7 @@ export default class TweetActionsBar extends PureComponent { onPress: PropTypes.func }) ), - style: PropTypes.object + style: ViewPropTypes.style }; render() { diff --git a/packages/benchmarks/src/components/TweetText/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetText.js similarity index 89% rename from packages/benchmarks/src/components/TweetText/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/TweetText.js index df922546f..4282788bf 100644 --- a/packages/benchmarks/src/components/TweetText/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetText.js @@ -1,6 +1,6 @@ -import AppText from '../AppText'; +import AppText from './AppText'; import React from 'react'; -import TweetTextPart from '../TweetTextPart'; +import TweetTextPart from './TweetTextPart'; import { array, number, string } from 'prop-types'; class TweetText extends React.Component { diff --git a/packages/benchmarks/src/components/TweetTextPart/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetTextPart.js similarity index 97% rename from packages/benchmarks/src/components/TweetTextPart/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/TweetTextPart.js index 6b15109f9..d758cc4b5 100644 --- a/packages/benchmarks/src/components/TweetTextPart/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/TweetTextPart.js @@ -2,7 +2,7 @@ import { Image, StyleSheet, Text } from 'react-native'; import PropTypes from 'prop-types'; import React from 'react'; -import theme from '../theme'; +import theme from './theme'; const createTextEntity = ({ part }) => {`${part.prefix}${part.text}`}; @@ -106,7 +106,7 @@ const styles = StyleSheet.create({ width: '1.25em', paddingRight: '0.05em', paddingLeft: '0.1em', - verticalAlign: '-0.2em' + textAlignVertical: '-0.2em' } }); diff --git a/packages/benchmarks/src/components/UserAvatar/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/UserAvatar.js similarity index 88% rename from packages/benchmarks/src/components/UserAvatar/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/UserAvatar.js index 831bc0515..017f3f1ad 100644 --- a/packages/benchmarks/src/components/UserAvatar/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/UserAvatar.js @@ -1,8 +1,8 @@ -import AspectRatio from '../AspectRatio'; +import AspectRatio from './AspectRatio'; import PropTypes from 'prop-types'; -import { Image, StyleSheet } from 'react-native'; +import { Image, StyleSheet, ViewPropTypes } from 'react-native'; import React, { PureComponent } from 'react'; -import theme from '../theme'; +import theme from './theme'; class UserAvatar extends PureComponent { static displayName = 'UserAvatar'; @@ -10,7 +10,7 @@ class UserAvatar extends PureComponent { static propTypes = { accessibilityLabel: PropTypes.string, circle: PropTypes.bool, - style: PropTypes.object, + style: ViewPropTypes.style, uri: PropTypes.string }; diff --git a/packages/benchmarks/src/components/UserNames/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/UserNames.js similarity index 90% rename from packages/benchmarks/src/components/UserNames/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/UserNames.js index a29d6c143..34600f03d 100644 --- a/packages/benchmarks/src/components/UserNames/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/UserNames.js @@ -1,6 +1,6 @@ -import AppText from '../AppText'; +import AppText from './AppText'; import PropTypes from 'prop-types'; -import { StyleSheet } from 'react-native'; +import { StyleSheet, ViewPropTypes } from 'react-native'; import React, { PureComponent } from 'react'; class UserNames extends PureComponent { @@ -11,7 +11,7 @@ class UserNames extends PureComponent { layout: PropTypes.oneOf(['nowrap', 'stack']), onPress: PropTypes.func, screenName: PropTypes.string, - style: PropTypes.object + style: ViewPropTypes.style }; static defaultProps = { diff --git a/packages/benchmarks/src/components/Tweet/index.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/index.js similarity index 93% rename from packages/benchmarks/src/components/Tweet/index.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/index.js index 928d08fb3..49752eb4b 100644 --- a/packages/benchmarks/src/components/Tweet/index.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/index.js @@ -1,13 +1,13 @@ -import AspectRatio from '../AspectRatio'; -import GridView from '../GridView'; +import AspectRatio from './AspectRatio'; +import GridView from './GridView'; import PropTypes from 'prop-types'; -import TweetActionsBar from '../TweetActionsBar'; -import TweetText from '../TweetText'; -import UserAvatar from '../UserAvatar'; -import UserNames from '../UserNames'; +import TweetActionsBar from './TweetActionsBar'; +import TweetText from './TweetText'; +import UserAvatar from './UserAvatar'; +import UserNames from './UserNames'; import { Image, StyleSheet, Text, View } from 'react-native'; import React, { Component } from 'react'; -import theme from '../theme'; +import theme from './theme'; export class Tweet extends Component { static displayName = 'Tweet'; diff --git a/packages/benchmarks/src/components/Icons/styles.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/styles.js similarity index 87% rename from packages/benchmarks/src/components/Icons/styles.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/styles.js index 380d7594d..217e4a60b 100644 --- a/packages/benchmarks/src/components/Icons/styles.js +++ b/packages/benchmarks/src/implementations/react-native-web/Tweet/styles.js @@ -8,7 +8,7 @@ const styles = StyleSheet.create({ maxWidth: '100%', position: 'relative', userSelect: 'none', - verticalAlign: 'text-bottom' + textAlignVertical: 'text-bottom' } }); diff --git a/packages/benchmarks/src/components/theme.js b/packages/benchmarks/src/implementations/react-native-web/Tweet/theme.js similarity index 100% rename from packages/benchmarks/src/components/theme.js rename to packages/benchmarks/src/implementations/react-native-web/Tweet/theme.js diff --git a/packages/benchmarks/src/implementations/react-native-web/index.js b/packages/benchmarks/src/implementations/react-native-web/index.js new file mode 100644 index 000000000..b6484e015 --- /dev/null +++ b/packages/benchmarks/src/implementations/react-native-web/index.js @@ -0,0 +1,11 @@ +import Box from './Box'; +import Dot from './Dot'; +import Tweet from './Tweet'; +import { View } from 'react-native'; + +export default { + Box, + Dot, + Tweet, + View +}; diff --git a/packages/benchmarks/src/components/Box/reactxp.js b/packages/benchmarks/src/implementations/reactxp/Box.js similarity index 100% rename from packages/benchmarks/src/components/Box/reactxp.js rename to packages/benchmarks/src/implementations/reactxp/Box.js diff --git a/packages/benchmarks/src/implementations/reactxp/Dot.js b/packages/benchmarks/src/implementations/reactxp/Dot.js new file mode 100644 index 000000000..6c1c49fb9 --- /dev/null +++ b/packages/benchmarks/src/implementations/reactxp/Dot.js @@ -0,0 +1,34 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; +import { Styles, View } from 'reactxp'; + +const Dot = ({ size, x, y, children, color }) => ( + +); + +const styles = { + root: Styles.createViewStyle({ + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + }) +}; + +export default Dot; diff --git a/packages/benchmarks/src/reactxp.js b/packages/benchmarks/src/implementations/reactxp/index.js similarity index 54% rename from packages/benchmarks/src/reactxp.js rename to packages/benchmarks/src/implementations/reactxp/index.js index 8e61561e1..e4c8da79b 100644 --- a/packages/benchmarks/src/reactxp.js +++ b/packages/benchmarks/src/implementations/reactxp/index.js @@ -1,7 +1,9 @@ -import Box from './components/Box/reactxp'; +import Box from './Box'; +import Dot from './Dot'; import { View } from 'reactxp'; export default { Box, + Dot, View }; diff --git a/packages/benchmarks/src/components/Box/styled-components.js b/packages/benchmarks/src/implementations/styled-components/Box.js similarity index 93% rename from packages/benchmarks/src/components/Box/styled-components.js rename to packages/benchmarks/src/implementations/styled-components/Box.js index b25e9e1ac..abba3ffa6 100644 --- a/packages/benchmarks/src/components/Box/styled-components.js +++ b/packages/benchmarks/src/implementations/styled-components/Box.js @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import View from '../View/styled-components'; +import View from './View'; const getColor = color => { switch (color) { diff --git a/packages/benchmarks/src/implementations/styled-components/Dot.js b/packages/benchmarks/src/implementations/styled-components/Dot.js new file mode 100644 index 000000000..6cebbe238 --- /dev/null +++ b/packages/benchmarks/src/implementations/styled-components/Dot.js @@ -0,0 +1,24 @@ +/* eslint-disable react/prop-types */ +import styled from 'styled-components'; +import View from './View'; + +const Dot = styled(View).attrs({ + style: props => ({ + left: `${props.x}px`, + top: `${props.y}px`, + borderRightWidth: `${props.size / 2}px`, + borderBottomWidth: `${props.size / 2}px`, + borderLeftWidth: `${props.size / 2}px`, + borderBottomColor: `${props.color}` + }) +})` + position: absolute; + cursor: pointer; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-top-width: 0; +`; + +export default Dot; diff --git a/packages/benchmarks/src/components/View/styled-components.js b/packages/benchmarks/src/implementations/styled-components/View.js similarity index 100% rename from packages/benchmarks/src/components/View/styled-components.js rename to packages/benchmarks/src/implementations/styled-components/View.js diff --git a/packages/benchmarks/src/implementations/styled-components/index.js b/packages/benchmarks/src/implementations/styled-components/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/styled-components/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/components/Box/styletron.js b/packages/benchmarks/src/implementations/styletron/Box.js similarity index 95% rename from packages/benchmarks/src/components/Box/styletron.js rename to packages/benchmarks/src/implementations/styletron/Box.js index 33f97e4e0..b27fe669c 100644 --- a/packages/benchmarks/src/components/Box/styletron.js +++ b/packages/benchmarks/src/implementations/styletron/Box.js @@ -1,7 +1,7 @@ /* eslint-disable react/prop-types */ import { injectStylePrefixed } from 'styletron-utils'; import React from 'react'; -import View, { styletron } from '../View/styletron'; +import View, { styletron } from './View'; const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( ( +
+ {children} +
+); + +const styles = { + root: injectStylePrefixed(styletron, { + position: 'absolute', + cursor: 'pointer', + width: 0, + height: 0, + borderColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0 + }) +}; + +export default Dot; diff --git a/packages/benchmarks/src/components/View/styletron.js b/packages/benchmarks/src/implementations/styletron/View.js similarity index 100% rename from packages/benchmarks/src/components/View/styletron.js rename to packages/benchmarks/src/implementations/styletron/View.js diff --git a/packages/benchmarks/src/implementations/styletron/index.js b/packages/benchmarks/src/implementations/styletron/index.js new file mode 100644 index 000000000..cdb1735ba --- /dev/null +++ b/packages/benchmarks/src/implementations/styletron/index.js @@ -0,0 +1,9 @@ +import Box from './Box'; +import Dot from './Dot'; +import View from './View'; + +export default { + Box, + Dot, + View +}; diff --git a/packages/benchmarks/src/index.js b/packages/benchmarks/src/index.js new file mode 100644 index 000000000..e829fd3bb --- /dev/null +++ b/packages/benchmarks/src/index.js @@ -0,0 +1,99 @@ +import aphrodite from './implementations/aphrodite'; +import cssModules from './implementations/css-modules'; +import emotion from './implementations/emotion'; +import jss from './implementations/jss'; +import glamor from './implementations/glamor'; +import inlineStyles from './implementations/inline-styles'; +import radium from './implementations/radium'; +import reactNativeWeb from './implementations/react-native-web'; +import reactxp from './implementations/reactxp'; +import styledComponents from './implementations/styled-components'; +import styletron from './implementations/styletron'; + +import renderDeepTree from './cases/renderDeepTree'; +import renderSierpinskiTriangle from './cases/renderSierpinskiTriangle'; +// import renderTweet from './cases/renderTweet'; +import renderWideTree from './cases/renderWideTree'; + +const testMatrix = { + 'inline-styles': [ + () => renderDeepTree('inline-styles', inlineStyles), + () => renderWideTree('inline-styles', inlineStyles), + () => renderSierpinskiTriangle('inline-styles', inlineStyles) + ], + 'css-modules': [ + () => renderDeepTree('css-modules', cssModules), + () => renderWideTree('css-modules', cssModules) + ], + 'react-native-web': [ + () => renderDeepTree('react-native-web', reactNativeWeb), + () => renderWideTree('react-native-web', reactNativeWeb), + () => renderSierpinskiTriangle('react-native-web', reactNativeWeb) + // () => renderTweet('react-native-web', reactNativeWeb) + ], + + aphrodite: [ + () => renderDeepTree('aphrodite', aphrodite), + () => renderWideTree('aphrodite', aphrodite) + ], + emotion: [ + () => renderDeepTree('emotion', emotion), + () => renderWideTree('emotion', emotion), + () => renderSierpinskiTriangle('emotion', emotion) + ], + glamor: [ + () => renderDeepTree('glamor', glamor), + () => renderWideTree('glamor', glamor) + // disabled: glamor starts to lock up the browser + // () => renderSierpinskiTriangle('glamor', glamor) + ], + jss: [() => renderDeepTree('jss', jss), () => renderWideTree('jss', jss)], + radium: [ + () => renderDeepTree('radium', radium), + () => renderWideTree('radium', radium), + () => renderSierpinskiTriangle('radium', radium) + ], + reactxp: [ + () => renderDeepTree('reactxp', reactxp), + () => renderWideTree('reactxp', reactxp), + () => renderSierpinskiTriangle('reactxp', reactxp) + ], + 'styled-components': [ + () => renderDeepTree('styled-components', styledComponents), + () => renderWideTree('styled-components', styledComponents), + () => renderSierpinskiTriangle('styled-components', styledComponents) + ], + styletron: [ + () => renderDeepTree('styletron', styletron), + () => renderWideTree('styletron', styletron), + () => renderSierpinskiTriangle('styletron', styletron) + ] +}; + +const allTests = Object.keys(testMatrix).reduce((acc, curr) => { + testMatrix[curr].forEach(test => { + acc.push(test); + }); + return acc; +}, []); + +const tests = []; + +if (window.location.search) { + window.location.search + .slice(1) + .split(',') + .forEach(implementation => { + if (Array.isArray(testMatrix[implementation])) { + tests.push(...testMatrix[implementation]); + } else { + throw new Error(`Benchmark for ${implementation} not found`); + } + }); +} else { + tests.push(...allTests); +} + +tests.push(() => () => Promise.resolve(console.log('Done'))); + +tests.reduce((promise, test) => promise.then(test()), Promise.resolve()); diff --git a/packages/benchmarks/src/jss.js b/packages/benchmarks/src/jss.js deleted file mode 100644 index 83867ad81..000000000 --- a/packages/benchmarks/src/jss.js +++ /dev/null @@ -1,9 +0,0 @@ -import Box from './components/Box/jss'; -import View from './components/View/jss'; - -const api = { - Box, - View -}; - -export default api; diff --git a/packages/benchmarks/src/radium.js b/packages/benchmarks/src/radium.js deleted file mode 100644 index ecfe03069..000000000 --- a/packages/benchmarks/src/radium.js +++ /dev/null @@ -1,9 +0,0 @@ -import Box from './components/Box/radium'; -import View from './components/View/radium'; - -const api = { - Box, - View -}; - -export default api; diff --git a/packages/benchmarks/src/react-native.js b/packages/benchmarks/src/react-native.js deleted file mode 100644 index 94d87aff3..000000000 --- a/packages/benchmarks/src/react-native.js +++ /dev/null @@ -1,9 +0,0 @@ -import Box from './components/Box/react-native'; -import Tweet from './components/Tweet'; -import { View } from 'react-native'; - -export default { - Box, - Tweet, - View -}; diff --git a/packages/benchmarks/src/styled-components.js b/packages/benchmarks/src/styled-components.js deleted file mode 100644 index 54272a8a1..000000000 --- a/packages/benchmarks/src/styled-components.js +++ /dev/null @@ -1,7 +0,0 @@ -import Box from './components/Box/styled-components'; -import View from './components/View/styled-components'; - -export default { - Box, - View -}; diff --git a/packages/benchmarks/src/styletron.js b/packages/benchmarks/src/styletron.js deleted file mode 100644 index 645380d57..000000000 --- a/packages/benchmarks/src/styletron.js +++ /dev/null @@ -1,7 +0,0 @@ -import Box from './components/Box/styletron'; -import View from './components/View/styletron'; - -export default { - Box, - View -}; diff --git a/packages/benchmarks/webpack.config.js b/packages/benchmarks/webpack.config.js index 9add3251f..ec1229c84 100644 --- a/packages/benchmarks/webpack.config.js +++ b/packages/benchmarks/webpack.config.js @@ -1,10 +1,10 @@ -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const path = require('path'); const webpack = require('webpack'); module.exports = { context: __dirname, - entry: './index', + entry: ['babel-polyfill', './src/index'], output: { path: path.resolve(__dirname, 'dist'), filename: 'performance.bundle.js' @@ -34,10 +34,10 @@ module.exports = { ] }, plugins: [ - new BundleAnalyzerPlugin({ - analyzerMode: 'static', - openAnalyzer: false - }), + // new BundleAnalyzerPlugin({ + // analyzerMode: 'static', + // openAnalyzer: false + // }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), diff --git a/yarn.lock b/yarn.lock index d763899aa..5a8c838dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2674,6 +2674,22 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +d3-color@1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b" + +d3-interpolate@1: + version "1.1.6" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.6.tgz#2cf395ae2381804df08aa1bf766b7f97b5f68fb6" + dependencies: + d3-color "1" + +d3-scale-chromatic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-1.1.1.tgz#811406e8e09dab78a49dac4a32047d5d3edd0c44" + dependencies: + d3-interpolate "1" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"