├── .gitignore
├── .jshintrc
├── README.md
├── benchmark-client
├── browser.json
├── client.js
├── components
│ ├── app
│ │ ├── component.js
│ │ └── index.marko
│ └── mount-container
│ │ ├── index.marko
│ │ └── style.css
├── createRoute.js
├── helpers.js
└── page.marko
├── benchmark-server
└── run.js
├── benchmarks.js
├── benchmarks
├── color-picker
│ ├── client.js
│ ├── colors.json
│ ├── createRoute.js
│ ├── inferno
│ │ ├── .babelrc
│ │ ├── client.jsx
│ │ ├── components
│ │ │ └── App.jsx
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ ├── server.jsx
│ │ └── util
│ │ │ └── serverRender.jsx
│ ├── marko
│ │ ├── client.js
│ │ ├── components
│ │ │ └── app
│ │ │ │ └── index.marko
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ └── server.js
│ ├── page.marko
│ ├── preact
│ │ ├── .babelrc
│ │ ├── client.jsx
│ │ ├── components
│ │ │ └── App.jsx
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ ├── server.jsx
│ │ └── util
│ │ │ └── serverRender.jsx
│ ├── react
│ │ ├── .babelrc
│ │ ├── client.jsx
│ │ ├── components
│ │ │ └── App.jsx
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ ├── server.jsx
│ │ └── util
│ │ │ └── serverRender.jsx
│ ├── server.js
│ ├── style.css
│ ├── svelte
│ │ ├── client.js
│ │ ├── components
│ │ │ └── App.html
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ ├── server.js
│ │ └── util
│ │ │ └── serverRender.js
│ ├── util
│ │ ├── search-results-data.json
│ │ └── search.js
│ └── vue
│ │ ├── .babelrc
│ │ ├── client.jsx
│ │ ├── components
│ │ └── App.jsx
│ │ ├── page.marko
│ │ ├── rollup.config.js
│ │ ├── server.jsx
│ │ └── util
│ │ └── serverRender.jsx
└── search-results
│ ├── client.js
│ ├── createRoute.js
│ ├── inferno
│ ├── .babelrc
│ ├── client.jsx
│ ├── components
│ │ ├── App.jsx
│ │ ├── Footer.jsx
│ │ └── SearchResultsItem.jsx
│ ├── page.marko
│ ├── rollup.config.js
│ ├── server.jsx
│ └── util
│ │ └── serverRender.jsx
│ ├── marko
│ ├── client.js
│ ├── components
│ │ ├── app-footer
│ │ │ └── index.marko
│ │ ├── app-search-results-item
│ │ │ └── index.marko
│ │ └── app
│ │ │ └── index.marko
│ ├── page.marko
│ ├── rollup.config.js
│ └── server.js
│ ├── page.marko
│ ├── preact
│ ├── .babelrc
│ ├── client.jsx
│ ├── components
│ │ ├── App.jsx
│ │ ├── Footer.jsx
│ │ └── SearchResultsItem.jsx
│ ├── page.marko
│ ├── rollup.config.js
│ ├── server.jsx
│ └── util
│ │ └── serverRender.jsx
│ ├── react
│ ├── .babelrc
│ ├── client.jsx
│ ├── components
│ │ ├── App.jsx
│ │ ├── Footer.jsx
│ │ └── SearchResultsItem.jsx
│ ├── page.marko
│ ├── rollup.config.js
│ ├── server.jsx
│ └── util
│ │ └── serverRender.jsx
│ ├── server.js
│ ├── svelte
│ ├── client.js
│ ├── components
│ │ ├── App.html
│ │ ├── Footer.html
│ │ └── SearchResultsItem.html
│ ├── page.marko
│ ├── rollup.config.js
│ ├── server.js
│ └── util
│ │ └── serverRender.js
│ ├── util
│ ├── search-results-data.json
│ └── search.js
│ └── vue
│ ├── .babelrc
│ ├── client.jsx
│ ├── components
│ ├── App.jsx
│ ├── Footer.jsx
│ └── SearchResultsItem.jsx
│ ├── page.marko
│ ├── rollup.config.js
│ ├── server.jsx
│ └── util
│ └── serverRender.jsx
├── images
├── test-image-01.jpg
├── test-image-02.jpg
├── test-image-03.jpg
├── test-image-04.jpg
├── test-image-05.jpg
└── test-image-06.jpg
├── index.marko
├── init.js
├── package.json
├── scripts
├── bundle.js
└── minify.js
├── server.js
└── util
└── runBenchmark.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.marko.js
2 | /node_modules
3 | /build
4 | /.cache
5 | .DS_Store
6 | /static
7 | npm-debug.log
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document"
4 | ],
5 | "node" : true,
6 | "esnext": true,
7 | "boss" : false,
8 | "curly": false,
9 | "debug": false,
10 | "devel": false,
11 | "eqeqeq": true,
12 | "evil": true,
13 | "forin": false,
14 | "immed": true,
15 | "laxbreak": false,
16 | "newcap": true,
17 | "noarg": true,
18 | "noempty": false,
19 | "nonew": true,
20 | "nomen": false,
21 | "onevar": false,
22 | "plusplus": false,
23 | "regexp": false,
24 | "undef": true,
25 | "sub": false,
26 | "white": false,
27 | "eqeqeq": false,
28 | "latedef": "func",
29 | "unused": "vars",
30 | "strict": false,
31 | "eqnull": true
32 | }
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | isomorphic-ui-benchmarks
2 | ========================================
3 |
4 | This repo includes multiple benchmarks for various UI libraries. Each benchmark is designed to measure rendering performance (on the server and in the browser) and the time that it takes to update the DOM (client-side only).
5 |
6 | # Current results
7 |
8 | Below are the results of a run on March 3, 2017
9 |
10 | Environment:
11 |
12 | - Node.js v7.5.0
13 | - MacBook Pro (15-inch, 2016)
14 | - Processor: 2.9 GHz Intel Core i7
15 | - Memory: 16 GB 2133 MHz LPDDR3
16 | - macOS Sierra: 10.12.3 (16D32)
17 | - Google Chrome Version 56.0.2924.87 (64-bit)
18 |
19 | ## Server-side
20 |
21 | ```
22 | Warming up...
23 |
24 | Warmup complete.
25 |
26 | Running "color-picker"...
27 |
28 | Running benchmark "inferno"...
29 |
30 | inferno x 2,053 ops/sec ±0.69% (86 runs sampled)
31 |
32 | Running benchmark "marko"...
33 |
34 | marko x 5,088 ops/sec ±6.54% (59 runs sampled)
35 |
36 | Running benchmark "preact"...
37 |
38 | preact x 3,252 ops/sec ±0.84% (88 runs sampled)
39 |
40 | Running benchmark "react"...
41 |
42 | react x 228 ops/sec ±2.84% (73 runs sampled)
43 |
44 | Running benchmark "svelte"...
45 |
46 | svelte x 14,911 ops/sec ±2.25% (80 runs sampled)
47 |
48 | Running benchmark "vue"...
49 |
50 | vue x 1,297 ops/sec ±3.68% (76 runs sampled)
51 |
52 | Fastest is svelte
53 |
54 | --------------
55 |
56 |
57 | Warming up...
58 |
59 | Warmup complete.
60 |
61 | Running "search-results"...
62 |
63 | Running benchmark "inferno"...
64 |
65 | inferno x 408 ops/sec ±0.64% (84 runs sampled)
66 |
67 | Running benchmark "marko"...
68 |
69 | marko x 1,993 ops/sec ±5.77% (62 runs sampled)
70 |
71 | Running benchmark "preact"...
72 |
73 | preact x 399 ops/sec ±0.94% (82 runs sampled)
74 |
75 | Running benchmark "react"...
76 |
77 | react x 37.00 ops/sec ±2.35% (48 runs sampled)
78 |
79 | Running benchmark "svelte"...
80 |
81 | svelte x 5,710 ops/sec ±3.54% (76 runs sampled)
82 |
83 | Running benchmark "vue"...
84 |
85 | vue x 166 ops/sec ±4.39% (70 runs sampled)
86 |
87 | Fastest is svelte
88 |
89 | --------------
90 | ```
91 |
92 | # Client-side
93 |
94 | ## Search results
95 |
96 | ### Google Chrome
97 |
98 | ```
99 | Warming up...
100 | Warmup complete.
101 | Running "search-results"...
102 | Running benchmark "inferno"...
103 | inferno x 165 ops/sec ±2.39% (55 runs sampled)
104 | Running benchmark "marko"...
105 | marko x 211 ops/sec ±1.56% (56 runs sampled)
106 | Running benchmark "preact"...
107 | preact x 188 ops/sec ±1.59% (56 runs sampled)
108 | Running benchmark "react"...
109 | react x 158 ops/sec ±2.16% (55 runs sampled)
110 | Running benchmark "svelte"...
111 | svelte x 332 ops/sec ±1.11% (57 runs sampled)
112 | Fastest is svelte
113 | ```
114 |
115 | ## Color picker
116 |
117 | ### Google Chrome
118 |
119 | ```
120 | Warming up...
121 | Warmup complete.
122 | Running "color-picker"...
123 | Running benchmark "inferno"...
124 | inferno x 2,766 ops/sec ±1.19% (59 runs sampled)
125 | Running benchmark "marko"...
126 | marko x 4,057 ops/sec ±2.76% (55 runs sampled)
127 | Running benchmark "preact"...
128 | preact x 2,719 ops/sec ±0.90% (60 runs sampled)
129 | Running benchmark "react"...
130 | react x 2,171 ops/sec ±1.66% (56 runs sampled)
131 | Running benchmark "svelte"...
132 | svelte x 7,449 ops/sec ±1.64% (40 runs sampled)
133 | Fastest is svelte
134 | ```
135 | # Additional details
136 |
137 | ## Included libraries
138 |
139 | The following UI libraries are currently included:
140 |
141 | - [inferno](https://github.com/infernojs/inferno)
142 | - [marko](https://github.com/marko-js/marko)
143 | - [preact](https://github.com/developit/preact)
144 | - [react](https://github.com/facebook/react)
145 | - [vue](https://github.com/vuejs/vue)
146 | - [svelte](https://github.com/sveltejs/svelte)
147 |
148 | ## Included benchmarks
149 |
150 | This repo currently includes the following benchmarks
151 |
152 | ### Search Results
153 |
154 | This benchmark measures the time it takes to render pages of search results. Each page includes 100 search result items. Every iteration renders an entirely new set of search results. As a result of rendering new search results for every cycle, a significant number of DOM nodes must be updated.
155 |
156 | ### Color Picker
157 |
158 | This benchmark measures the time it takes to cycle through a selected color. The selected color index changes every cycle. When the selected color index changes two things happen:
159 |
160 | - The new selected color is highlighted
161 | - The old selected color is unhighlighted
162 | - The selected color is shown at the end
163 |
164 | Compared to the search results benchmark, there are a relatively small number of changes to the DOM for every cycle.
165 |
166 | # Running the benchmarks
167 |
168 | ## Install
169 |
170 | ```bash
171 | git clone https://github.com/marko-js/isomorphic-ui-benchmarks.git
172 | cd isomorphic-ui-benchmarks
173 | npm install
174 | npm run build # Build client-side JS bundles
175 | ```
176 |
177 | ## Run server-side benchmarks
178 |
179 | ```bash
180 | npm run benchmarks
181 | ```
182 |
183 | ## Run client-side benchmarks
184 |
185 | Start
186 |
187 | ```bash
188 | npm start
189 | ```
190 |
191 | Open [http://localhost:8080/](http://localhost:8080/) in your browser and choose a benchmark to run.
192 |
193 | # Contributions and Feedback
194 |
195 | If you see any problems or have any suggestions please let us know. Every effort was made to be as fair and accurate as possible, but mistakes do happen. If you find a problem please open a Github issue to discuss.
196 |
--------------------------------------------------------------------------------
/benchmark-client/browser.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | "lodash/lodash.js",
4 | "benchmark/benchmark.js",
5 | "require: ./components/app"
6 | ]
7 | }
--------------------------------------------------------------------------------
/benchmark-client/client.js:
--------------------------------------------------------------------------------
1 | var helpers = require('./helpers');
2 |
3 | function addBench(libName, factoryFunc) {
4 | var benchmark = exports.benchmark;
5 | var bench = benchmark.createBench(libName, factoryFunc);
6 | benchmark.benches[libName] = bench;
7 | }
8 |
9 | function registerBenchmark(factoryFunc) {
10 | var benchmark = factoryFunc(helpers);
11 | benchmark.benches = {};
12 | exports.benchmark = benchmark;
13 | }
14 |
15 | if (typeof window !== 'undefined') {
16 | window.addBench = addBench;
17 | window.registerBenchmark = registerBenchmark;
18 | window.onMount = function() {};
19 | }
--------------------------------------------------------------------------------
/benchmark-client/components/app/component.js:
--------------------------------------------------------------------------------
1 | var runBenchmark = require('~/util/runBenchmark');
2 | var client = require('../../client');
3 |
4 | var Benchmark = typeof window !== 'undefined' && window.Benchmark;
5 |
6 | module.exports = {
7 | onInput: function(input) {
8 | this.state = {
9 | running: false,
10 | benchmarkName: input.benchmark.name
11 | };
12 | },
13 |
14 | handleBenchmarkButtonClick: function(event, el) {
15 | if (this.state.running) {
16 | return;
17 | }
18 |
19 | var benchmarkName = this.state.benchmarkName;
20 |
21 | var oldButtonLabel = el.innerHTML;
22 | el.innerHTML = oldButtonLabel + ' - running...';
23 |
24 | var resultsEl = this.getEl('results');
25 | resultsEl.innerHTML = '';
26 |
27 | var self = this;
28 |
29 | runBenchmark(benchmarkName, client.benchmark, Benchmark)
30 | .on('start', function(event) {
31 | resultsEl.innerHTML += 'Running "' + benchmarkName + '"...\n';
32 | })
33 | .on('startBench', function(bench) {
34 | resultsEl.innerHTML += 'Running benchmark "' + bench.name + '"...\n';
35 | })
36 | .on('warmup', function() {
37 | resultsEl.innerHTML += 'Warming up...\n';
38 | })
39 | .on('warmupComplete', function() {
40 | resultsEl.innerHTML += 'Warmup complete.\n';
41 | })
42 | .on('cycle', function(event) {
43 | resultsEl.innerHTML += event.resultsString + '\n';
44 | })
45 | .on('complete', function(event) {
46 | resultsEl.innerHTML += event.resultsString + '\n';
47 | el.innerHTML = oldButtonLabel;
48 | self.running = false;
49 | })
50 | .run()
51 | .catch(function(err) {
52 | resultsEl.innerHTML = err.stack || err;
53 | console.error('ERROR:', err.stack || err);
54 | });
55 |
56 | }
57 | };
--------------------------------------------------------------------------------
/benchmark-client/components/app/index.marko:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/benchmark-client/components/mount-container/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 |
3 | }
4 |
5 |
6 | ${data.libName}
7 |
11 |
--------------------------------------------------------------------------------
/benchmark-client/components/mount-container/style.css:
--------------------------------------------------------------------------------
1 | .mount-container {
2 | height: 600px;
3 | width: 300px;
4 | overflow: scroll;
5 | display: inline-block;
6 | }
--------------------------------------------------------------------------------
/benchmark-client/createRoute.js:
--------------------------------------------------------------------------------
1 | var template = require('./page.marko');
2 |
3 | var isProduction = process.env.NODE_ENV === 'production';
4 |
5 | function createRoute(benchmark, routeOptions) {
6 | var bundles = [];
7 | benchmark.benches.forEach((bench) => {
8 | // if (bench.name !== 'marko') {
9 | // return;
10 | // }
11 | bundles.push(`/build/${benchmark.name}/bundles${isProduction ? '.min' : ''}/${bench.name}.js`);
12 | });
13 |
14 | return function(req, res) {
15 | res.marko(template, {
16 | $global: {
17 | benchmark
18 | },
19 | bundles
20 | });
21 | };
22 | }
23 |
24 | module.exports = createRoute;
25 |
--------------------------------------------------------------------------------
/benchmark-client/helpers.js:
--------------------------------------------------------------------------------
1 | var mountContainer = require('./components/mount-container');
2 |
3 | var mountEls = {};
4 |
5 | function createMountEl(libName) {
6 | var key = libName;
7 | var mountedComponent = mountContainer.renderSync({
8 | libName: libName
9 | })
10 | .appendTo(document.getElementById('mount'))
11 | .getComponent();
12 |
13 | mountEls[key] = mountedComponent.el;
14 |
15 | return mountedComponent.getEl('output');
16 | }
17 |
18 | function showSingleMountEl(libName) {
19 | var key = libName;
20 |
21 | for (var curKey in mountEls) {
22 | var mountEl = mountEls[curKey];
23 | if (curKey === key) {
24 | mountEl.style.display = 'inline-block';
25 | } else {
26 | mountEl.style.display = 'none';
27 | }
28 | }
29 | }
30 |
31 | function showMountEl(libName) {
32 | var key = libName;
33 |
34 | var mountEl = mountEls[key];
35 | mountEl.style.display = 'inline-block';
36 | }
37 |
38 | exports.createMountEl = createMountEl;
39 | exports.showSingleMountEl = showSingleMountEl;
40 | exports.showMountEl = showMountEl;
--------------------------------------------------------------------------------
/benchmark-client/page.marko:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 |
4 | $ var dependencies = [
5 | require.resolve("./browser.json"),
6 | "require-run: " + require.resolve('./client'),
7 | "require-run: " + require.resolve('../benchmarks/' + out.global.benchmark.name + "/client.js")
8 | ];
9 |
10 |
11 |
12 |
13 |
14 |
15 | ${out.global.benchmark.name} | Marko Benchmark
16 |
17 |
18 |
19 |
20 | ${out.global.benchmark.name} | Marko Benchmark
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/benchmark-server/run.js:
--------------------------------------------------------------------------------
1 | require('require-self-ref');
2 |
3 | require("babel-register")({
4 | // and .js so you'll have to add them back if you want them to be used again.
5 | extensions: [".jsx"]
6 | });
7 |
8 | var benchmarks = require('../benchmarks');
9 | var util_runBenchmark = require('~/util/runBenchmark');
10 | var Benchmark = require('benchmark');
11 |
12 | function runBenchmark(benchmark) {
13 | var benchmarkConfig = {
14 | benches: {}
15 | };
16 |
17 | benchmark.benches.forEach((bench) => {
18 | benchmarkConfig.benches[bench.name] = benchmark.serverFactory(bench);
19 | });
20 |
21 | return util_runBenchmark(benchmark.name, benchmarkConfig, Benchmark)
22 | .on('start', function(event) {
23 | console.log('Running "' + benchmark.name + '"...\n');
24 | })
25 | .on('startBench', function(bench) {
26 | if (global.gc) {
27 | // Run garbage collection before each bench
28 | global.gc();
29 | }
30 |
31 | console.log('Running benchmark "' + bench.name + '"...\n');
32 | })
33 | .on('warmup', function() {
34 | console.log('Warming up...\n');
35 | })
36 | .on('warmupComplete', function() {
37 | console.log('Warmup complete.\n');
38 | })
39 | .on('cycle', function(event) {
40 | console.log(event.resultsString + '\n');
41 | })
42 | .on('complete', function(event) {
43 | console.log(event.resultsString + '\n');
44 | })
45 | .run();
46 | }
47 |
48 | function runAll() {
49 | var promiseChain = Promise.resolve();
50 |
51 | benchmarks.forEach((benchmark) => {
52 | promiseChain = promiseChain.then(() => {
53 | return runBenchmark(benchmark);
54 | });
55 | });
56 |
57 | return promiseChain;
58 | }
59 |
60 | runAll()
61 | .then(() => {
62 | console.log('DONE!');
63 | })
64 | .catch((err) => {
65 | console.error('ERROR:', (err.stack || err));
66 | process.exit(1);
67 | });
--------------------------------------------------------------------------------
/benchmarks.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var path = require('path');
3 |
4 | var benchmarksDir = path.join(__dirname, 'benchmarks');
5 |
6 | var benchmarks = [];
7 |
8 |
9 |
10 | var enabledLibs = null;
11 | var enabledBenchmarks = null;
12 |
13 | // enabledLibs = {
14 | // preact: false,
15 | // react: false,
16 | // marko: true,
17 | // vue: false,
18 | // inferno: false
19 | // };
20 | //
21 | // enabledBenchmarks = {
22 | // 'search-results': true,
23 | // 'color-picker': false
24 | // };
25 |
26 | fs.readdirSync(benchmarksDir).forEach((benchmarkName) => {
27 | var benchmarkDir = path.join(benchmarksDir, benchmarkName);
28 |
29 | if (!fs.statSync(benchmarkDir).isDirectory()) {
30 | // Only look at directories
31 | return;
32 | }
33 |
34 | if (enabledBenchmarks && !enabledBenchmarks[benchmarkName]) {
35 | return;
36 | }
37 |
38 | var benchmark = {
39 | name: benchmarkName,
40 | dir: benchmarkDir,
41 | benches: [],
42 | createRoute: require(path.join(benchmarkDir, 'createRoute')),
43 | serverFactory: require(path.join(benchmarkDir, 'server'))
44 | };
45 |
46 | benchmarks.push(benchmark);
47 |
48 | fs.readdirSync(benchmarkDir).forEach((libName) => {
49 | if (libName === 'util') {
50 | return;
51 | }
52 |
53 | if (enabledLibs && !enabledLibs[libName]) {
54 | return;
55 | }
56 |
57 | var libDir = path.join(benchmarkDir, libName);
58 | if (!fs.statSync(libDir).isDirectory()) {
59 | // Only look at directories
60 | return;
61 | }
62 | var bench = {
63 | dir: libDir,
64 | name: libName,
65 | url: `/${benchmarkName}/${libName}`,
66 | serverFactory: require(path.join(libDir, 'server'))
67 |
68 | };
69 |
70 | benchmark.benches.push(bench);
71 | });
72 | });
73 |
74 | module.exports = benchmarks;
--------------------------------------------------------------------------------
/benchmarks/color-picker/client.js:
--------------------------------------------------------------------------------
1 | var colors = require('./colors.json');
2 |
3 | window.registerBenchmark(function(helpers) {
4 | return {
5 | createBench: function(libName, factoryFunc) {
6 | var mountEl = helpers.createMountEl(libName);
7 | var pageIndex = 0;
8 |
9 |
10 | var fn = factoryFunc(mountEl, colors);
11 |
12 | return {
13 | onWarmup: function() {
14 | pageIndex = 0;
15 | helpers.showMountEl(libName);
16 | },
17 | onStart: function() {
18 | pageIndex = 0;
19 | helpers.showSingleMountEl(libName);
20 | },
21 | fn
22 | };
23 | }
24 | };
25 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/colors.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "hex": "#EFDECD",
4 | "name": "Almond",
5 | "rgb": "(239, 222, 205)"
6 | },
7 | {
8 | "hex": "#CD9575",
9 | "name": "Antique Brass",
10 | "rgb": "(205, 149, 117)"
11 | },
12 | {
13 | "hex": "#FDD9B5",
14 | "name": "Apricot",
15 | "rgb": "(253, 217, 181)"
16 | },
17 | {
18 | "hex": "#78DBE2",
19 | "name": "Aquamarine",
20 | "rgb": "(120, 219, 226)"
21 | },
22 | {
23 | "hex": "#87A96B",
24 | "name": "Asparagus",
25 | "rgb": "(135, 169, 107)"
26 | },
27 | {
28 | "hex": "#FFA474",
29 | "name": "Atomic Tangerine",
30 | "rgb": "(255, 164, 116)"
31 | },
32 | {
33 | "hex": "#FAE7B5",
34 | "name": "Banana Mania",
35 | "rgb": "(250, 231, 181)"
36 | },
37 | {
38 | "hex": "#9F8170",
39 | "name": "Beaver",
40 | "rgb": "(159, 129, 112)"
41 | },
42 | {
43 | "hex": "#FD7C6E",
44 | "name": "Bittersweet",
45 | "rgb": "(253, 124, 110)"
46 | },
47 | {
48 | "hex": "#000000",
49 | "name": "Black",
50 | "rgb": "(0,0,0)"
51 | },
52 | {
53 | "hex": "#ACE5EE",
54 | "name": "Blizzard Blue",
55 | "rgb": "(172, 229, 238)"
56 | },
57 | {
58 | "hex": "#1F75FE",
59 | "name": "Blue",
60 | "rgb": "(31, 117, 254)"
61 | },
62 | {
63 | "hex": "#A2A2D0",
64 | "name": "Blue Bell",
65 | "rgb": "(162, 162, 208)"
66 | },
67 | {
68 | "hex": "#6699CC",
69 | "name": "Blue Gray",
70 | "rgb": "(102, 153, 204)"
71 | },
72 | {
73 | "hex": "#0D98BA",
74 | "name": "Blue Green",
75 | "rgb": "(13, 152, 186)"
76 | },
77 | {
78 | "hex": "#7366BD",
79 | "name": "Blue Violet",
80 | "rgb": "(115, 102, 189)"
81 | },
82 | {
83 | "hex": "#DE5D83",
84 | "name": "Blush",
85 | "rgb": "(222, 93, 131)"
86 | },
87 | {
88 | "hex": "#CB4154",
89 | "name": "Brick Red",
90 | "rgb": "(203, 65, 84)"
91 | },
92 | {
93 | "hex": "#B4674D",
94 | "name": "Brown",
95 | "rgb": "(180, 103, 77)"
96 | },
97 | {
98 | "hex": "#FF7F49",
99 | "name": "Burnt Orange",
100 | "rgb": "(255, 127, 73)"
101 | },
102 | {
103 | "hex": "#EA7E5D",
104 | "name": "Burnt Sienna",
105 | "rgb": "(234, 126, 93)"
106 | },
107 | {
108 | "hex": "#B0B7C6",
109 | "name": "Cadet Blue",
110 | "rgb": "(176, 183, 198)"
111 | },
112 | {
113 | "hex": "#FFFF99",
114 | "name": "Canary",
115 | "rgb": "(255, 255, 153)"
116 | },
117 | {
118 | "hex": "#1CD3A2",
119 | "name": "Caribbean Green",
120 | "rgb": "(28, 211, 162)"
121 | },
122 | {
123 | "hex": "#FFAACC",
124 | "name": "Carnation Pink",
125 | "rgb": "(255, 170, 204)"
126 | },
127 | {
128 | "hex": "#DD4492",
129 | "name": "Cerise",
130 | "rgb": "(221, 68, 146)"
131 | },
132 | {
133 | "hex": "#1DACD6",
134 | "name": "Cerulean",
135 | "rgb": "(29, 172, 214)"
136 | },
137 | {
138 | "hex": "#BC5D58",
139 | "name": "Chestnut",
140 | "rgb": "(188, 93, 88)"
141 | },
142 | {
143 | "hex": "#DD9475",
144 | "name": "Copper",
145 | "rgb": "(221, 148, 117)"
146 | },
147 | {
148 | "hex": "#9ACEEB",
149 | "name": "Cornflower",
150 | "rgb": "(154, 206, 235)"
151 | },
152 | {
153 | "hex": "#FFBCD9",
154 | "name": "Cotton Candy",
155 | "rgb": "(255, 188, 217)"
156 | },
157 | {
158 | "hex": "#FDDB6D",
159 | "name": "Dandelion",
160 | "rgb": "(253, 219, 109)"
161 | },
162 | {
163 | "hex": "#2B6CC4",
164 | "name": "Denim",
165 | "rgb": "(43, 108, 196)"
166 | },
167 | {
168 | "hex": "#EFCDB8",
169 | "name": "Desert Sand",
170 | "rgb": "(239, 205, 184)"
171 | },
172 | {
173 | "hex": "#6E5160",
174 | "name": "Eggplant",
175 | "rgb": "(110, 81, 96)"
176 | },
177 | {
178 | "hex": "#CEFF1D",
179 | "name": "Electric Lime",
180 | "rgb": "(206, 255, 29)"
181 | },
182 | {
183 | "hex": "#71BC78",
184 | "name": "Fern",
185 | "rgb": "(113, 188, 120)"
186 | },
187 | {
188 | "hex": "#6DAE81",
189 | "name": "Forest Green",
190 | "rgb": "(109, 174, 129)"
191 | },
192 | {
193 | "hex": "#C364C5",
194 | "name": "Fuchsia",
195 | "rgb": "(195, 100, 197)"
196 | },
197 | {
198 | "hex": "#CC6666",
199 | "name": "Fuzzy Wuzzy",
200 | "rgb": "(204, 102, 102)"
201 | },
202 | {
203 | "hex": "#E7C697",
204 | "name": "Gold",
205 | "rgb": "(231, 198, 151)"
206 | },
207 | {
208 | "hex": "#FCD975",
209 | "name": "Goldenrod",
210 | "rgb": "(252, 217, 117)"
211 | },
212 | {
213 | "hex": "#A8E4A0",
214 | "name": "Granny Smith Apple",
215 | "rgb": "(168, 228, 160)"
216 | },
217 | {
218 | "hex": "#95918C",
219 | "name": "Gray",
220 | "rgb": "(149, 145, 140)"
221 | },
222 | {
223 | "hex": "#1CAC78",
224 | "name": "Green",
225 | "rgb": "(28, 172, 120)"
226 | },
227 | {
228 | "hex": "#1164B4",
229 | "name": "Green Blue",
230 | "rgb": "(17, 100, 180)"
231 | },
232 | {
233 | "hex": "#F0E891",
234 | "name": "Green Yellow",
235 | "rgb": "(240, 232, 145)"
236 | },
237 | {
238 | "hex": "#FF1DCE",
239 | "name": "Hot Magenta",
240 | "rgb": "(255, 29, 206)"
241 | },
242 | {
243 | "hex": "#B2EC5D",
244 | "name": "Inchworm",
245 | "rgb": "(178, 236, 93)"
246 | },
247 | {
248 | "hex": "#5D76CB",
249 | "name": "Indigo",
250 | "rgb": "(93, 118, 203)"
251 | },
252 | {
253 | "hex": "#CA3767",
254 | "name": "Jazzberry Jam",
255 | "rgb": "(202, 55, 103)"
256 | },
257 | {
258 | "hex": "#3BB08F",
259 | "name": "Jungle Green",
260 | "rgb": "(59, 176, 143)"
261 | },
262 | {
263 | "hex": "#FEFE22",
264 | "name": "Laser Lemon",
265 | "rgb": "(254, 254, 34)"
266 | },
267 | {
268 | "hex": "#FCB4D5",
269 | "name": "Lavender",
270 | "rgb": "(252, 180, 213)"
271 | },
272 | {
273 | "hex": "#FFF44F",
274 | "name": "Lemon Yellow",
275 | "rgb": "(255, 244, 79)"
276 | },
277 | {
278 | "hex": "#FFBD88",
279 | "name": "Macaroni and Cheese",
280 | "rgb": "(255, 189, 136)"
281 | },
282 | {
283 | "hex": "#F664AF",
284 | "name": "Magenta",
285 | "rgb": "(246, 100, 175)"
286 | },
287 | {
288 | "hex": "#AAF0D1",
289 | "name": "Magic Mint",
290 | "rgb": "(170, 240, 209)"
291 | },
292 | {
293 | "hex": "#CD4A4C",
294 | "name": "Mahogany",
295 | "rgb": "(205, 74, 76)"
296 | },
297 | {
298 | "hex": "#EDD19C",
299 | "name": "Maize",
300 | "rgb": "(237, 209, 156)"
301 | },
302 | {
303 | "hex": "#979AAA",
304 | "name": "Manatee",
305 | "rgb": "(151, 154, 170)"
306 | },
307 | {
308 | "hex": "#FF8243",
309 | "name": "Mango Tango",
310 | "rgb": "(255, 130, 67)"
311 | },
312 | {
313 | "hex": "#C8385A",
314 | "name": "Maroon",
315 | "rgb": "(200, 56, 90)"
316 | },
317 | {
318 | "hex": "#EF98AA",
319 | "name": "Mauvelous",
320 | "rgb": "(239, 152, 170)"
321 | },
322 | {
323 | "hex": "#FDBCB4",
324 | "name": "Melon",
325 | "rgb": "(253, 188, 180)"
326 | },
327 | {
328 | "hex": "#1A4876",
329 | "name": "Midnight Blue",
330 | "rgb": "(26, 72, 118)"
331 | },
332 | {
333 | "hex": "#30BA8F",
334 | "name": "Mountain Meadow",
335 | "rgb": "(48, 186, 143)"
336 | },
337 | {
338 | "hex": "#C54B8C",
339 | "name": "Mulberry",
340 | "rgb": "(197, 75, 140)"
341 | },
342 | {
343 | "hex": "#1974D2",
344 | "name": "Navy Blue",
345 | "rgb": "(25, 116, 210)"
346 | },
347 | {
348 | "hex": "#FFA343",
349 | "name": "Neon Carrot",
350 | "rgb": "(255, 163, 67)"
351 | },
352 | {
353 | "hex": "#BAB86C",
354 | "name": "Olive Green",
355 | "rgb": "(186, 184, 108)"
356 | },
357 | {
358 | "hex": "#FF7538",
359 | "name": "Orange",
360 | "rgb": "(255, 117, 56)"
361 | },
362 | {
363 | "hex": "#FF2B2B",
364 | "name": "Orange Red",
365 | "rgb": "(255, 43, 43)"
366 | },
367 | {
368 | "hex": "#F8D568",
369 | "name": "Orange Yellow",
370 | "rgb": "(248, 213, 104)"
371 | },
372 | {
373 | "hex": "#E6A8D7",
374 | "name": "Orchid",
375 | "rgb": "(230, 168, 215)"
376 | },
377 | {
378 | "hex": "#414A4C",
379 | "name": "Outer Space",
380 | "rgb": "(65, 74, 76)"
381 | },
382 | {
383 | "hex": "#FF6E4A",
384 | "name": "Outrageous Orange",
385 | "rgb": "(255, 110, 74)"
386 | },
387 | {
388 | "hex": "#1CA9C9",
389 | "name": "Pacific Blue",
390 | "rgb": "(28, 169, 201)"
391 | },
392 | {
393 | "hex": "#FFCFAB",
394 | "name": "Peach",
395 | "rgb": "(255, 207, 171)"
396 | },
397 | {
398 | "hex": "#C5D0E6",
399 | "name": "Periwinkle",
400 | "rgb": "(197, 208, 230)"
401 | },
402 | {
403 | "hex": "#FDDDE6",
404 | "name": "Piggy Pink",
405 | "rgb": "(253, 221, 230)"
406 | },
407 | {
408 | "hex": "#158078",
409 | "name": "Pine Green",
410 | "rgb": "(21, 128, 120)"
411 | },
412 | {
413 | "hex": "#FC74FD",
414 | "name": "Pink Flamingo",
415 | "rgb": "(252, 116, 253)"
416 | },
417 | {
418 | "hex": "#F78FA7",
419 | "name": "Pink Sherbet",
420 | "rgb": "(247, 143, 167)"
421 | },
422 | {
423 | "hex": "#8E4585",
424 | "name": "Plum",
425 | "rgb": "(142, 69, 133)"
426 | },
427 | {
428 | "hex": "#7442C8",
429 | "name": "Purple Heart",
430 | "rgb": "(116, 66, 200)"
431 | },
432 | {
433 | "hex": "#9D81BA",
434 | "name": "Purple Mountain's Majesty",
435 | "rgb": "(157, 129, 186)"
436 | },
437 | {
438 | "hex": "#FE4EDA",
439 | "name": "Purple Pizzazz",
440 | "rgb": "(254, 78, 218)"
441 | },
442 | {
443 | "hex": "#FF496C",
444 | "name": "Radical Red",
445 | "rgb": "(255, 73, 108)"
446 | },
447 | {
448 | "hex": "#D68A59",
449 | "name": "Raw Sienna",
450 | "rgb": "(214, 138, 89)"
451 | },
452 | {
453 | "hex": "#714B23",
454 | "name": "Raw Umber",
455 | "rgb": "(113, 75, 35)"
456 | },
457 | {
458 | "hex": "#FF48D0",
459 | "name": "Razzle Dazzle Rose",
460 | "rgb": "(255, 72, 208)"
461 | },
462 | {
463 | "hex": "#E3256B",
464 | "name": "Razzmatazz",
465 | "rgb": "(227, 37, 107)"
466 | },
467 | {
468 | "hex": "#EE204D",
469 | "name": "Red",
470 | "rgb": "(238,32 ,77 )"
471 | },
472 | {
473 | "hex": "#FF5349",
474 | "name": "Red Orange",
475 | "rgb": "(255, 83, 73)"
476 | },
477 | {
478 | "hex": "#C0448F",
479 | "name": "Red Violet",
480 | "rgb": "(192, 68, 143)"
481 | },
482 | {
483 | "hex": "#1FCECB",
484 | "name": "Robin's Egg Blue",
485 | "rgb": "(31, 206, 203)"
486 | },
487 | {
488 | "hex": "#7851A9",
489 | "name": "Royal Purple",
490 | "rgb": "(120, 81, 169)"
491 | },
492 | {
493 | "hex": "#FF9BAA",
494 | "name": "Salmon",
495 | "rgb": "(255, 155, 170)"
496 | },
497 | {
498 | "hex": "#FC2847",
499 | "name": "Scarlet",
500 | "rgb": "(252, 40, 71)"
501 | },
502 | {
503 | "hex": "#76FF7A",
504 | "name": "Screamin' Green",
505 | "rgb": "(118, 255, 122)"
506 | },
507 | {
508 | "hex": "#9FE2BF",
509 | "name": "Sea Green",
510 | "rgb": "(159, 226, 191)"
511 | },
512 | {
513 | "hex": "#A5694F",
514 | "name": "Sepia",
515 | "rgb": "(165, 105, 79)"
516 | },
517 | {
518 | "hex": "#8A795D",
519 | "name": "Shadow",
520 | "rgb": "(138, 121, 93)"
521 | },
522 | {
523 | "hex": "#45CEA2",
524 | "name": "Shamrock",
525 | "rgb": "(69, 206, 162)"
526 | },
527 | {
528 | "hex": "#FB7EFD",
529 | "name": "Shocking Pink",
530 | "rgb": "(251, 126, 253)"
531 | },
532 | {
533 | "hex": "#CDC5C2",
534 | "name": "Silver",
535 | "rgb": "(205, 197, 194)"
536 | },
537 | {
538 | "hex": "#80DAEB",
539 | "name": "Sky Blue",
540 | "rgb": "(128, 218, 235)"
541 | },
542 | {
543 | "hex": "#ECEABE",
544 | "name": "Spring Green",
545 | "rgb": "(236, 234, 190)"
546 | },
547 | {
548 | "hex": "#FFCF48",
549 | "name": "Sunglow",
550 | "rgb": "(255, 207, 72)"
551 | },
552 | {
553 | "hex": "#FD5E53",
554 | "name": "Sunset Orange",
555 | "rgb": "(253, 94, 83)"
556 | },
557 | {
558 | "hex": "#FAA76C",
559 | "name": "Tan",
560 | "rgb": "(250, 167, 108)"
561 | },
562 | {
563 | "hex": "#18A7B5",
564 | "name": "Teal Blue",
565 | "rgb": "(24, 167, 181)"
566 | },
567 | {
568 | "hex": "#EBC7DF",
569 | "name": "Thistle",
570 | "rgb": "(235, 199, 223)"
571 | },
572 | {
573 | "hex": "#FC89AC",
574 | "name": "Tickle Me Pink",
575 | "rgb": "(252, 137, 172)"
576 | },
577 | {
578 | "hex": "#DBD7D2",
579 | "name": "Timberwolf",
580 | "rgb": "(219, 215, 210)"
581 | },
582 | {
583 | "hex": "#17806D",
584 | "name": "Tropical Rain Forest",
585 | "rgb": "(23, 128, 109)"
586 | },
587 | {
588 | "hex": "#DEAA88",
589 | "name": "Tumbleweed",
590 | "rgb": "(222, 170, 136)"
591 | },
592 | {
593 | "hex": "#77DDE7",
594 | "name": "Turquoise Blue",
595 | "rgb": "(119, 221, 231)"
596 | },
597 | {
598 | "hex": "#FFFF66",
599 | "name": "Unmellow Yellow",
600 | "rgb": "(255, 255, 102)"
601 | },
602 | {
603 | "hex": "#926EAE",
604 | "name": "Violet (Purple)",
605 | "rgb": "(146, 110, 174)"
606 | },
607 | {
608 | "hex": "#324AB2",
609 | "name": "Violet Blue",
610 | "rgb": "(50, 74, 178)"
611 | },
612 | {
613 | "hex": "#F75394",
614 | "name": "Violet Red",
615 | "rgb": "(247, 83, 148)"
616 | },
617 | {
618 | "hex": "#FFA089",
619 | "name": "Vivid Tangerine",
620 | "rgb": "(255, 160, 137)"
621 | },
622 | {
623 | "hex": "#8F509D",
624 | "name": "Vivid Violet",
625 | "rgb": "(143, 80, 157)"
626 | },
627 | {
628 | "hex": "#FFFFFF",
629 | "name": "White",
630 | "rgb": "(255, 255, 255)"
631 | },
632 | {
633 | "hex": "#A2ADD0",
634 | "name": "Wild Blue Yonder",
635 | "rgb": "(162, 173, 208)"
636 | },
637 | {
638 | "hex": "#FF43A4",
639 | "name": "Wild Strawberry",
640 | "rgb": "(255, 67, 164)"
641 | },
642 | {
643 | "hex": "#FC6C85",
644 | "name": "Wild Watermelon",
645 | "rgb": "(252, 108, 133)"
646 | },
647 | {
648 | "hex": "#CDA4DE",
649 | "name": "Wisteria",
650 | "rgb": "(205, 164, 222)"
651 | },
652 | {
653 | "hex": "#FCE883",
654 | "name": "Yellow",
655 | "rgb": "(252, 232, 131)"
656 | },
657 | {
658 | "hex": "#C5E384",
659 | "name": "Yellow Green",
660 | "rgb": "(197, 227, 132)"
661 | },
662 | {
663 | "hex": "#FFAE42",
664 | "name": "Yellow Orange",
665 | "rgb": "(255, 174, 66)"
666 | }
667 | ]
--------------------------------------------------------------------------------
/benchmarks/color-picker/createRoute.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('marko/node-require');
3 | var pageLayoutTemplate = require('./page.marko');
4 |
5 | var colors = require('./colors.json');
6 |
7 | module.exports = function createRoute(libName, options) {
8 | var pageTemplate = require(`./${libName}/page.marko`);
9 |
10 | return function(req, res) {
11 | res.setHeader('Content-Type', 'text/html; charset=utf-8');
12 |
13 | pageTemplate.render({
14 | $global: {
15 | jsBundle: options.jsBundle,
16 | title: libName
17 | },
18 | pageLayout: pageLayoutTemplate,
19 | colors: colors
20 | }, res);
21 |
22 | res.on('error', function(err) {
23 | console.error('ERROR:', err);
24 | });
25 | };
26 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0"
5 | ],
6 | "plugins": ["inferno"]
7 | }
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/client.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var render = Inferno.render;
3 |
4 | var App = require('./components/App');
5 |
6 | var mountNode = document.getElementById("mount");
7 |
8 | if (window.colors) {
9 | render(
10 | ,
11 | mountNode);
12 |
13 | console.log('Re-rendering on client completed');
14 | }
15 |
16 | window.addBench('inferno', function(el, colors) {
17 | var widget;
18 | var currentDone;
19 | var selectedColorIndex = 0;
20 |
21 | function onMount(instance) {
22 | widget = instance;
23 | }
24 |
25 | function onUpdate() {
26 | if (currentDone) {
27 | currentDone();
28 | }
29 | }
30 |
31 | render(
32 | ,
33 | el);
34 |
35 |
36 | return function(done) {
37 | widget.setState({
38 | selectedColorIndex: (++selectedColorIndex) % colors.length
39 | });
40 |
41 | currentDone = done;
42 |
43 | };
44 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/components/App.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var Component = require('inferno-component');
3 |
4 | module.exports = class extends Component {
5 | constructor(props) {
6 | super(props);
7 | this.state = {
8 | selectedColorIndex: 0
9 | };
10 | }
11 |
12 | componentDidMount() {
13 | if (this.props.onMount) {
14 | this.props.onMount(this);
15 | }
16 |
17 | window.onMount();
18 | }
19 |
20 | componentDidUpdate() {
21 | if (this.props.onUpdate) {
22 | this.props.onUpdate(this);
23 | }
24 | }
25 |
26 | handleColorClick(colorIndex) {
27 | this.setState({
28 | selectedColorIndex: colorIndex
29 | });
30 | }
31 |
32 | render() {
33 | var colors = this.props.colors;
34 | var handleColorClick = this.handleColorClick;
35 | var selectedColorIndex = this.state.selectedColorIndex;
36 | var selectedColor = colors[selectedColorIndex];
37 | var self = this;
38 |
39 | function renderColor(color, i) {
40 | var style = {
41 | backgroundColor: color.hex
42 | };
43 |
44 | var className = 'color';
45 | if (selectedColorIndex === i) {
46 | className += ' selected';
47 | }
48 |
49 | return (
50 | {color.name}
51 | )
52 | }
53 |
54 | function renderColors(colors) {
55 | if (colors.length) {
56 | return ({colors.map(function(color, i) {
57 | return renderColor(color, i);
58 | })}
);
59 | } else {
60 | return No colors!
61 | }
62 | }
63 |
64 | return (
65 |
66 |
Choose your favorite color:
67 |
68 | {renderColors(colors)}
69 |
70 |
71 | You chose:
72 |
{selectedColor.name}
73 |
74 |
75 | );
76 | }
77 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML=serverRender(App, input.colors);
7 |
8 | $!{renderedHTML}
9 |
20 |
23 | @body>
24 |
25 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | browserifyPlugin(envify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.jsx' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'inferno.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/server.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var InfernoServer = require('inferno-server');
3 | var App = require('./components/App');
4 |
5 | module.exports = function(colors) {
6 | return function benchFn() {
7 | var html = InfernoServer.renderToString(
8 | );
9 |
10 | return html;
11 | };
12 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/inferno/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var InfernoServer = require('inferno-server');
3 |
4 | module.exports = function infernoRender(App, colors) {
5 | return InfernoServer.renderToString(
6 | );
7 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/marko/client.js:
--------------------------------------------------------------------------------
1 | var app = require('./components/app');
2 | require('marko/components').init();
3 |
4 | window.addBench('marko', function(el, colors) {
5 |
6 | var component = app.renderSync({ colors: colors })
7 | .appendTo(el)
8 | .getComponent();
9 |
10 | var selectedColorIndex = 0;
11 |
12 | return function(done) {
13 | component.state.selectedColorIndex = (++selectedColorIndex) % colors.length;
14 | component.update();
15 | done();
16 | };
17 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/marko/components/app/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | constructor() {
3 | this.state = {
4 | selectedColorIndex: 0
5 | };
6 | }
7 |
8 | onMount() {
9 | window.onMount();
10 | }
11 |
12 | handleColorClick(colorIndex) {
13 | this.state.selectedColorIndex = colorIndex;
14 | }
15 | }
16 |
17 | $ var colors = input.colors;
18 | $ var selectedColorIndex = state.selectedColorIndex;
19 | $ var selectedColor = colors[selectedColorIndex];
20 |
21 |
22 | Choose your favorite color:
23 |
24 |
25 |
26 | $ {
27 | var className = 'color';
28 | if (selectedColorIndex === i) {
29 | className += ' selected';
30 | }
31 | }
32 | -
34 | ${color.name}
35 |
36 |
37 |
38 |
39 | No colors!
40 |
41 |
42 |
43 | You chose:
44 |
${selectedColor.name}
45 |
46 |
47 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/marko/page.marko:
--------------------------------------------------------------------------------
1 |
2 | <@body>
3 |
4 | @body>
5 |
6 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/marko/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import markoify from 'markoify';
5 | import envify from 'envify';
6 | import minpropsify from 'minprops/browserify';
7 | import path from 'path';
8 |
9 | export default {
10 | entry: path.join(__dirname, 'client.js'),
11 | format: 'iife',
12 | moduleName: 'app',
13 | plugins: [
14 | browserifyPlugin(markoify),
15 | browserifyPlugin(envify),
16 | browserifyPlugin(minpropsify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.marko' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.marko', '**/*.js'],
26 | extensions: [ '.js', '.marko' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'marko.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/marko/server.js:
--------------------------------------------------------------------------------
1 | var app = require('./components/app');
2 |
3 | module.exports = function(colors) {
4 | return function benchFn() {
5 | var html = app.renderToString({
6 | colors: colors
7 | });
8 |
9 | return html;
10 | };
11 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/page.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${out.global.title} • Isomorphic UI Benchmarks
6 |
7 |
8 |
9 | ${out.global.title} • Isomorphic UI Benchmarks
10 |
11 |
12 |
13 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0"
5 | ],
6 | "plugins": [
7 | [ "transform-react-jsx", { "pragma": "h" } ],
8 | ["transform-es2015-block-scoping"]
9 | ]
10 | }
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/client.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var render = preact.render;
4 |
5 | var App = require('./components/App');
6 |
7 | var mountNode = document.getElementById("mount");
8 |
9 | if (window.colors) {
10 | render(
11 | ,
12 | mountNode,
13 | mountNode.firstChild);
14 |
15 | console.log('Re-rendering on client completed');
16 | }
17 |
18 | window.addBench('preact', function(el, colors) {
19 | var widget;
20 | var currentDone;
21 | var selectedColorIndex = 0;
22 |
23 | function onMount(instance) {
24 | widget = instance;
25 | }
26 |
27 | function onUpdate() {
28 | currentDone();
29 | }
30 |
31 | render(
32 | ,
33 | el);
34 |
35 |
36 |
37 | return function(done) {
38 | widget.setState({
39 | selectedColorIndex: (++selectedColorIndex) % colors.length
40 | });
41 |
42 | currentDone = done;
43 |
44 | };
45 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/components/App.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var preact = require('preact');
3 | var h = preact.h;
4 | var Component = preact.Component;
5 |
6 | module.exports = class extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | selectedColorIndex: 0
11 | };
12 | }
13 |
14 | componentDidMount() {
15 | if (this.props.onMount) {
16 | this.props.onMount(this);
17 | }
18 | window.onMount();
19 | }
20 |
21 | componentDidUpdate() {
22 | if (this.props.onUpdate) {
23 | this.props.onUpdate(this);
24 | }
25 | }
26 |
27 | handleColorClick(colorIndex) {
28 | this.setState({
29 | selectedColorIndex: colorIndex
30 | });
31 | }
32 |
33 | render() {
34 | var colors = this.props.colors;
35 | var handleColorClick = this.handleColorClick;
36 | var selectedColorIndex = this.state.selectedColorIndex;
37 | var selectedColor = colors[selectedColorIndex];
38 | var self = this;
39 |
40 | function renderColor(color, i) {
41 | var style = {
42 | backgroundColor: color.hex
43 | };
44 |
45 | var className = 'color';
46 | if (selectedColorIndex === i) {
47 | className += ' selected';
48 | }
49 |
50 | return (
51 | {color.name}
52 | )
53 | }
54 |
55 | function renderColors(colors) {
56 | if (colors.length) {
57 | return ({colors.map(function(color, i) {
58 | return renderColor(color, i);
59 | })}
);
60 | } else {
61 | return No colors!
62 | }
63 | }
64 |
65 | return (
66 |
67 |
Choose your favorite color:
68 |
69 | {renderColors(colors)}
70 |
71 |
72 | You chose:
73 |
{selectedColor.name}
74 |
75 |
76 | );
77 | }
78 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML = serverRender(App, input.colors);
7 |
8 | $!{renderedHTML}
9 |
20 |
23 | @body>
24 |
25 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | process.env.NODE_ENV = 'production';
9 |
10 | // NODE_ENV=production browserify -t envify -t markoify --extension='.marko' --global-transform minprops/browserify -o build/bundles/marko.js marko/client.js
11 |
12 |
13 | export default {
14 | entry: path.join(__dirname, 'client.jsx'),
15 | format: 'iife',
16 | moduleName: 'app',
17 | plugins: [
18 | babelPlugin({
19 | // include: ['node_modules/**', '**/*.js', '**/*.jsx']
20 | }),
21 | browserifyPlugin(envify),
22 | nodeResolvePlugin({
23 | jsnext: false, // Default: false
24 | main: true, // Default: true
25 | browser: true, // Default: false
26 | preferBuiltins: false,
27 | extensions: [ '.js', '.jsx' ]
28 | }),
29 | commonjsPlugin({
30 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
31 | extensions: [ '.js', '.jsx' ]
32 | })
33 | ],
34 | dest: path.join(process.env.BUNDLES_DIR, 'preact.js')
35 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/server.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var renderToString = require('preact-render-to-string');
4 |
5 | var App = require('./components/App');
6 |
7 | module.exports = function(colors) {
8 | return function benchFn() {
9 |
10 | var html = renderToString(
11 | );
12 |
13 | return html;
14 | };
15 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/preact/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var renderToString = require('preact-render-to-string');
4 |
5 | module.exports = function reactRender(App, colors) {
6 | return renderToString(
7 | );
8 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0",
5 | "react"
6 | ],
7 | "plugins": ["transform-react-constant-elements"]
8 | }
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/client.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var App = require('./components/App');
5 |
6 | var mountNode = document.getElementById("mount");
7 |
8 | if (window.colors) {
9 | ReactDOM.render(
10 | ,
11 | mountNode);
12 |
13 | console.log('Re-rendering on client completed');
14 | }
15 |
16 | window.addBench('react', function(el, colors) {
17 | var widget;
18 |
19 | function onMount(instance) {
20 | widget = instance;
21 | }
22 |
23 | ReactDOM.render(
24 | ,
25 | el);
26 |
27 |
28 | var selectedColorIndex = 0;
29 |
30 | return function(done) {
31 | widget.setState({
32 | selectedColorIndex: (++selectedColorIndex) % colors.length
33 | }, done);
34 | };
35 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/components/App.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var React = require('react');
3 |
4 | function renderColor(color) {
5 | var style = {
6 | backgroundColor: color
7 | };
8 |
9 | return
10 | {color}
11 |
12 | }
13 |
14 | function renderColors(colors) {
15 | if (colors.length) {
16 | return ({colors.map(renderColor)}
);
17 | } else {
18 | return No colors!
19 | }
20 | }
21 |
22 | module.exports = class extends React.Component {
23 | constructor(props) {
24 | super(props);
25 | this.state = {
26 | selectedColorIndex: 0
27 | };
28 | }
29 |
30 | componentDidMount() {
31 | if (this.props.onMount) {
32 | this.props.onMount(this);
33 | }
34 | window.onMount();
35 | }
36 |
37 | handleColorClick(colorIndex) {
38 | this.setState({
39 | selectedColorIndex: colorIndex
40 | });
41 | }
42 |
43 | render() {
44 | var colors = this.props.colors;
45 | var handleColorClick = this.handleColorClick;
46 | var selectedColorIndex = this.state.selectedColorIndex;
47 | var selectedColor = colors[selectedColorIndex];
48 | var self = this;
49 |
50 | function renderColor(color, i) {
51 | var style = {
52 | backgroundColor: color.hex
53 | };
54 |
55 | var className = 'color';
56 | if (selectedColorIndex === i) {
57 | className += ' selected';
58 | }
59 |
60 | return (
61 | {color.name}
62 | )
63 | }
64 |
65 | function renderColors(colors) {
66 | if (colors.length) {
67 | return ({colors.map(function(color, i) {
68 | return renderColor(color, i);
69 | })}
);
70 | } else {
71 | return No colors!
72 | }
73 | }
74 |
75 | return (
76 |
77 |
Choose your favorite color:
78 |
79 | {renderColors(colors)}
80 |
81 |
82 | You chose:
83 |
{selectedColor.name}
84 |
85 |
86 | );
87 | }
88 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML=serverRender(App, input.colors);
7 | $!{renderedHTML}
8 |
19 |
22 | @body>
23 |
24 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | browserifyPlugin(envify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.jsx' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'react.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/server.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 |
4 | var App = require('./components/App');
5 |
6 | module.exports = function(colors) {
7 | return function benchFn() {
8 |
9 | var html = ReactDOMServer.renderToString(
10 | );
11 |
12 | return html;
13 | };
14 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/react/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 |
4 | module.exports = function reactRender(App, colors) {
5 | return ReactDOMServer.renderToString(
6 | );
7 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('marko/node-require');
3 |
4 | var colors = require('./colors.json');
5 | module.exports = function(bench) {
6 | var serverFactory = bench.serverFactory;
7 | var fn = serverFactory(colors);
8 | return {
9 | fn
10 | };
11 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/style.css:
--------------------------------------------------------------------------------
1 | .colors .color {
2 | box-sizing: border-box;
3 | border: 2px solid white;
4 | cursor: pointer;
5 | }
6 |
7 | .colors .color.selected {
8 | border: 2px solid black;
9 | }
10 | .colors ul {
11 | margin: 0;
12 | padding-left: 0;
13 | list-style: none;
14 | }
15 |
16 | .colors li {
17 | margin: 0;
18 | display: inline-block;
19 | width: 150px;
20 | height: 3em;
21 | text-align: center;
22 | line-height: 3em;
23 | vertical-align: middle;
24 | }
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/client.js:
--------------------------------------------------------------------------------
1 | import App from './components/App.html';
2 |
3 | var mountNode = document.getElementById("mount");
4 |
5 | if (window.colors) {
6 | mountNode.innerHTML = '';
7 |
8 | var colors = window.colors;
9 | const app = new App({
10 | target: mountNode,
11 | data: { colors }
12 | });
13 |
14 | console.log('Re-rendering on client completed');
15 | }
16 |
17 | window.addBench('svelte', function(el, colors) {
18 | var widget;
19 | var selectedColorIndex = 0;
20 |
21 | var widget = new App({
22 | target: el,
23 | data: { colors }
24 | });
25 |
26 | return function(done) {
27 | widget.set({
28 | selectedColorIndex: (++selectedColorIndex) % colors.length
29 | });
30 | done();
31 | };
32 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/components/App.html:
--------------------------------------------------------------------------------
1 |
2 |
Choose your favorite color:
3 |
4 | {{#if colors.length}}
5 |
6 | {{#each colors as color, i}}
7 | -
11 | {{color.name}}
12 |
13 | {{/each}}
14 |
15 | {{else}}
16 |
17 | No colors!
18 |
19 | {{/if}}
20 |
21 |
22 | You chose:
23 |
{{selectedColor.name}}
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/page.marko:
--------------------------------------------------------------------------------
1 | import 'svelte/ssr/register';
2 | import serverRender from './util/serverRender';
3 | import App from './components/App.html';
4 |
5 |
6 | <@body>
7 |
8 | $ serverRender(App, input, out);
9 |
10 |
13 | @body>
14 |
15 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/rollup.config.js:
--------------------------------------------------------------------------------
1 | import bublePlugin from 'rollup-plugin-buble';
2 | import sveltePlugin from 'rollup-plugin-svelte';
3 | import path from 'path';
4 |
5 | export default {
6 | entry: path.join(__dirname, 'client.js'),
7 | format: 'iife',
8 | moduleName: 'app',
9 | plugins: [
10 | sveltePlugin(),
11 | bublePlugin()
12 | ],
13 | dest: path.join(process.env.BUNDLES_DIR, 'svelte.js')
14 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/server.js:
--------------------------------------------------------------------------------
1 | require('svelte/ssr/register');
2 |
3 | var App = require('./components/App.html');
4 |
5 | module.exports = function(colors) {
6 | return function benchFn(done) {
7 | const html = App.render({ colors });
8 | done();
9 | return html;
10 | };
11 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/svelte/util/serverRender.js:
--------------------------------------------------------------------------------
1 | module.exports = function serverRender(App, input, out) {
2 | const html = App.render({ colors: input.colors });
3 | out.beginAsync().end(html);
4 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/util/search.js:
--------------------------------------------------------------------------------
1 | var searchResultsData = require('./search-results-input.json');
2 |
3 | exports.performSearch = function(input) {
4 | var pageIndex = input.pageIndex || 0;
5 | var pageSize = 100;
6 | var start = pageIndex * pageSize;
7 |
8 | var items = [];
9 |
10 | for (var i=start; i
11 | }
12 | });
13 |
14 | app.$mount('#mount');
15 |
16 | console.log('Re-rendering on client completed');
17 | }
18 |
19 | window.addBench('vue', function(el, colors) {
20 | var widget;
21 | var currentDone;
22 | var selectedColorIndex = 0;
23 |
24 | function onMount(instance) {
25 | widget = instance;
26 | }
27 |
28 | // function onUpdate() {
29 | // currentDone();
30 | // }
31 |
32 | const app = new Vue({
33 | data: {
34 | colors: colors
35 | },
36 |
37 | render(h) {
38 | return
39 | }
40 | });
41 |
42 | app.$mount(el);
43 |
44 | return function(done) {
45 | widget.selectedColorIndex = (++selectedColorIndex) % colors.length;
46 | widget.$nextTick(done);
47 | };
48 | });
--------------------------------------------------------------------------------
/benchmarks/color-picker/vue/components/App.jsx:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var Vue = require('vue');
4 |
5 | module.exports = {
6 | mounted() {
7 | if (this.handleMount) {
8 | this.handleMount(this);
9 | }
10 | window.onMount();
11 | },
12 | updated() {
13 | if (this.handleUpdate) {
14 | this.handleUpdate(this);
15 | }
16 | },
17 | props: ['colors', 'handleMount', 'handleUpdate'],
18 | data: function() {
19 | return {
20 | selectedColorIndex: 0
21 | }
22 | },
23 | methods: {
24 | handleColorClick: function(colorIndex) {
25 | this.selectedColorIndex = colorIndex;
26 | }
27 | },
28 | render(h) {
29 | var colors = this.colors;
30 | var handleColorClick = this.handleColorClick;
31 | var selectedColorIndex = this.selectedColorIndex;
32 | var selectedColor = colors[selectedColorIndex];
33 | var self = this;
34 |
35 | function renderColor(color, i) {
36 | var style = {
37 | backgroundColor: color.hex
38 | };
39 |
40 | return (
41 | {color.name}
42 | )
43 | }
44 |
45 | function renderColors(h, colors) {
46 | if (colors.length) {
47 | return ({colors.map(function(color, i) {
48 | return renderColor(color, i);
49 | })}
);
50 | } else {
51 | return No colors!
52 | }
53 | }
54 |
55 | return (
56 |
57 |
Choose your favorite color:
58 |
59 | {renderColors(h, colors)}
60 |
61 |
62 | You chose:
63 |
{selectedColor.name}
64 |
65 |
66 | );
67 | }
68 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/vue/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender'
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 |
7 | $ serverRender(App, input, out);
8 |
9 |
12 | @body>
13 |
14 |
--------------------------------------------------------------------------------
/benchmarks/color-picker/vue/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | nodeResolvePlugin({
17 | jsnext: false, // Default: false
18 | main: true, // Default: true
19 | browser: true, // Default: false
20 | preferBuiltins: false,
21 | extensions: [ '.js', '.jsx' ]
22 | }),
23 | // browserifyPlugin(envify),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'vue.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/vue/server.jsx:
--------------------------------------------------------------------------------
1 | const Vue = require('Vue');
2 | const renderToString = require('vue-server-renderer').createRenderer().renderToString;
3 |
4 |
5 | var App = require('./components/App');
6 |
7 | module.exports = function(colors) {
8 | return function benchFn(done) {
9 |
10 | const vm = new Vue({
11 | render(h) {
12 | return
13 | }
14 | });
15 |
16 | renderToString(vm, function(err, html) {
17 | if (err) {
18 | throw err;
19 | }
20 |
21 | done();
22 |
23 | return html;
24 | });
25 | };
26 | };
--------------------------------------------------------------------------------
/benchmarks/color-picker/vue/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | const Vue = require('Vue');
2 | const renderToString = require('vue-server-renderer').createRenderer().renderToString;
3 |
4 | module.exports = function serverRender(App, input, out) {
5 | const vm = new Vue({
6 | render(h) {
7 | return
8 | }
9 | });
10 |
11 | var asyncOut = out.beginAsync();
12 |
13 | return renderToString(vm, function(err, html) {
14 | if (err) {
15 | throw err;
16 | }
17 |
18 | asyncOut.end(html);
19 | });
20 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/client.js:
--------------------------------------------------------------------------------
1 | var searchService = require('./util/search');
2 |
3 | window.registerBenchmark(function(helpers) {
4 | return {
5 | createBench: function(libName, factoryFunc) {
6 | var mountEl = helpers.createMountEl(libName);
7 | var pageIndex = 0;
8 |
9 | function getNextSearchResults() {
10 | return searchService.performSearch({ pageIndex: pageIndex++ });
11 | }
12 |
13 | var fn = factoryFunc(mountEl, getNextSearchResults);
14 |
15 | return {
16 | onWarmup: function() {
17 | pageIndex = 0;
18 | helpers.showMountEl(libName);
19 | },
20 | onStart: function() {
21 | pageIndex = 0;
22 | helpers.showSingleMountEl(libName);
23 | },
24 | fn
25 | };
26 | }
27 | };
28 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/createRoute.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('marko/node-require');
3 |
4 | var searchService = require('./util/search');
5 | var pageLayoutTemplate = require('./page.marko');
6 |
7 | module.exports = function createRoute(libName, options) {
8 | var pageTemplate = require(`./${libName}/page.marko`);
9 |
10 | return function(req, res) {
11 | res.setHeader('Content-Type', 'text/html; charset=utf-8');
12 |
13 | pageTemplate.render({
14 | $global: {
15 | jsBundle: options.jsBundle,
16 | title: libName
17 | },
18 | pageLayout: pageLayoutTemplate,
19 | searchResults: searchService.performSearch({})
20 | }, res);
21 | };
22 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0"
5 | ],
6 | "plugins": ["inferno"]
7 | }
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/client.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 |
3 | var App = require('./components/App');
4 |
5 | var mountNode = document.getElementById("searchResultsMount");
6 |
7 | if (mountNode) {
8 | Inferno.render(
9 | ,
10 | mountNode);
11 |
12 | console.log('Re-rendering on client completed');
13 | }
14 |
15 | window.addBench('inferno', function(el, getNextSearchResults) {
16 | Inferno.render(
17 | ,
18 | el);
19 |
20 | return function(done) {
21 | Inferno.render(
22 | ,
23 | el);
24 |
25 | done();
26 | };
27 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/components/App.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var Component = require('inferno-component');
3 | var SearchResultsItem = require('./SearchResultsItem');
4 | var Footer = require('./Footer');
5 |
6 | module.exports = class extends Component {
7 | componentDidMount() {
8 | window.onMount();
9 | }
10 |
11 | render() {
12 | var searchResultsData = this.props.searchResultsData;
13 |
14 | return (
15 |
16 |
17 | {searchResultsData.items.map(function(item, i) {
18 | return
19 | })}
20 |
21 |
22 |
23 | );
24 | }
25 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/components/SearchResultsItem.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var Component = require('inferno-component');
3 | var linkEvent = Inferno.linkEvent;
4 |
5 | function handleBuyButtonClick(instance, event) {
6 | instance.setState({ 'purchased': true });
7 | }
8 |
9 | module.exports = class extends Component {
10 | constructor(props) {
11 | super(props);
12 |
13 | this.state = {
14 | purchased: false
15 | };
16 | }
17 |
18 | componentWillReceiveProps(props) {
19 | this.setState({
20 | purchased: false
21 | });
22 | }
23 |
24 | render() {
25 | var item = this.props.item;
26 | var style = { backgroundColor: this.state.purchased ? '#f1c40f' : ''};
27 |
28 | return (
29 |
30 |
{item.title}
31 |
32 |
39 |
40 |
{item.price}
41 |
42 | {this.state.purchased ?
43 |
Purchased!
:
44 |
47 | }
48 |
49 |
50 | );
51 | }
52 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML=serverRender(App, input.searchResults);
7 |
8 | $!{renderedHTML}
9 |
20 |
23 | @body>
24 |
25 |
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | browserifyPlugin(envify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.jsx' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'inferno.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/server.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var InfernoServer = require('inferno-server');
3 | var App = require('./components/App');
4 |
5 | module.exports = function(getNextSearchResults) {
6 | return function benchFn() {
7 |
8 | var html = InfernoServer.renderToString(
9 | );
10 |
11 | return html;
12 | };
13 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/inferno/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var Inferno = require('inferno');
2 | var InfernoServer = require('inferno-server');
3 |
4 | module.exports = function infernoRender(App, searchResultsData) {
5 | return InfernoServer.renderToString(
6 | );
7 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/client.js:
--------------------------------------------------------------------------------
1 | var app = require('./components/app');
2 | require('marko/components').init();
3 |
4 | window.addBench('marko', function(el, getNextSearchResults) {
5 |
6 | var component = app.renderSync(getNextSearchResults())
7 | .appendTo(el)
8 | .getComponent();
9 |
10 | return function(done) {
11 | component.input = getNextSearchResults();
12 | component.update();
13 | done();
14 | };
15 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/components/app-search-results-item/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | onInput(input) {
3 | this.state = {
4 | purchased: false
5 | };
6 | }
7 |
8 | handleBuyButtonClick() {
9 | this.state.purchased = true;
10 | }
11 | }
12 |
13 |
14 |
${input.title}
15 |
16 |
23 |
24 |
${input.price}
25 |
26 | Purchased!
27 |
28 |
29 |
30 | Buy now!
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/components/app/index.marko:
--------------------------------------------------------------------------------
1 | class {
2 | onInput() {
3 | this.input = null;
4 | }
5 |
6 | onMount() {
7 | window.onMount();
8 | }
9 | }
10 |
11 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/page.marko:
--------------------------------------------------------------------------------
1 |
2 | <@body>
3 |
4 | @body>
5 |
6 |
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import markoify from 'markoify';
5 | import envify from 'envify';
6 | import minpropsify from 'minprops/browserify';
7 | import path from 'path';
8 |
9 | export default {
10 | entry: path.join(__dirname, 'client.js'),
11 | format: 'iife',
12 | moduleName: 'app',
13 | plugins: [
14 | browserifyPlugin(markoify),
15 | browserifyPlugin(envify),
16 | browserifyPlugin(minpropsify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.marko' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.marko', '**/*.js'],
26 | extensions: [ '.js', '.marko' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'marko.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/marko/server.js:
--------------------------------------------------------------------------------
1 | var app = require('./components/app');
2 |
3 | module.exports = function(getNextSearchResults) {
4 | return function benchFn() {
5 | var html = app.renderToString(getNextSearchResults());
6 | return html;
7 | };
8 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/page.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ${out.global.title} • Isomorphic UI Benchmarks
6 |
7 |
8 | ${out.global.title} • Isomorphic UI Benchmarks
9 |
10 |
11 |
12 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0"
5 | ],
6 | "plugins": [
7 | [ "transform-react-jsx", { "pragma": "h" } ],
8 | ["transform-es2015-block-scoping"]
9 | ]
10 | }
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/client.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var render = preact.render;
4 |
5 | var App = require('./components/App');
6 |
7 | var mountNode = document.getElementById("searchResultsMount");
8 |
9 | if (mountNode) {
10 | render(
11 | ,
12 | mountNode,
13 | mountNode.firstChild);
14 |
15 | console.log('Re-rendering on client completed');
16 | }
17 |
18 | window.addBench('preact', function(el, getNextSearchResults) {
19 | render(
20 | ,
21 | el);
22 |
23 | return function(done) {
24 | render(
25 | ,
26 | el,
27 | el.firstChild);
28 |
29 | done();
30 | };
31 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/components/App.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var Component = preact.Component;
4 |
5 | var SearchResultsItem = require('./SearchResultsItem');
6 | var Footer = require('./Footer');
7 |
8 | module.exports = class extends Component {
9 | componentDidMount() {
10 | window.onMount();
11 | }
12 |
13 | render() {
14 | var searchResultsData = this.props.searchResultsData;
15 |
16 | return (
17 |
18 |
19 | {searchResultsData.items.map(function(item, i) {
20 | return
21 | })}
22 |
23 |
24 |
25 | );
26 | }
27 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/components/SearchResultsItem.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var Component = preact.Component;
4 |
5 | module.exports = class extends Component {
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = {
10 | purchased: false,
11 | item: this.props.item
12 | };
13 |
14 | this.handleBuyButtonClick = this.handleBuyButtonClick.bind(this);
15 | }
16 |
17 | componentWillReceiveProps(props) {
18 | this.state = {
19 | purchased: false
20 | };
21 | }
22 |
23 | handleBuyButtonClick() {
24 | this.setState({ 'purchased': true });
25 | }
26 |
27 | render() {
28 | var item = this.props.item;
29 | var style = { backgroundColor: this.state.purchased ? '#f1c40f' : ''};
30 |
31 | return (
32 |
33 |
{item.title}
34 |
41 |
42 |
{item.price}
43 |
44 | {this.state.purchased ?
45 |
Purchased!
:
46 |
49 | }
50 |
51 |
52 | );
53 | }
54 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML = serverRender(App, input.searchResults);
7 | $!{renderedHTML}
8 |
19 |
22 | @body>
23 |
24 |
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | process.env.NODE_ENV = 'production';
9 |
10 | // NODE_ENV=production browserify -t envify -t markoify --extension='.marko' --global-transform minprops/browserify -o build/bundles/marko.js marko/client.js
11 |
12 |
13 | export default {
14 | entry: path.join(__dirname, 'client.jsx'),
15 | format: 'iife',
16 | moduleName: 'app',
17 | plugins: [
18 | babelPlugin({
19 | // include: ['node_modules/**', '**/*.js', '**/*.jsx']
20 | }),
21 | browserifyPlugin(envify),
22 | nodeResolvePlugin({
23 | jsnext: false, // Default: false
24 | main: true, // Default: true
25 | browser: true, // Default: false
26 | preferBuiltins: false,
27 | extensions: [ '.js', '.jsx' ]
28 | }),
29 | commonjsPlugin({
30 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
31 | extensions: [ '.js', '.jsx' ]
32 | })
33 | ],
34 | dest: path.join(process.env.BUNDLES_DIR, 'preact.js')
35 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/server.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var renderToString = require('preact-render-to-string');
4 |
5 | var App = require('./components/App');
6 |
7 | module.exports = function(getNextSearchResults) {
8 | return function benchFn() {
9 |
10 | var html = renderToString(
11 | );
12 |
13 | return html;
14 | };
15 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/preact/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var preact = require('preact');
2 | var h = preact.h;
3 | var renderToString = require('preact-render-to-string');
4 |
5 | module.exports = function reactRender(App, searchResultsData) {
6 | return renderToString(
7 | );
8 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "loose": true, "modules": false }],
4 | "stage-0",
5 | "react"
6 | ],
7 | "plugins": ["transform-react-constant-elements"]
8 | }
--------------------------------------------------------------------------------
/benchmarks/search-results/react/client.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOM = require('react-dom');
3 |
4 | var App = require('./components/App');
5 |
6 | var mountNode = document.getElementById("searchResultsMount");
7 |
8 | if (mountNode) {
9 | ReactDOM.render(
10 | ,
11 | mountNode);
12 |
13 | console.log('Re-rendering on client completed');
14 | }
15 |
16 | window.addBench('react', function(el, getNextSearchResults) {
17 | ReactDOM.render(
18 | ,
19 | el);
20 |
21 | return function(done) {
22 | ReactDOM.render(
23 | ,
24 | el,
25 | done);
26 | };
27 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/react/components/App.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var SearchResultsItem = require('./SearchResultsItem');
3 | var Footer = require('./Footer');
4 |
5 | module.exports = class extends React.Component {
6 | componentDidMount() {
7 | window.onMount();
8 | }
9 |
10 | render() {
11 | var searchResultsData = this.props.searchResultsData;
12 |
13 | return (
14 |
15 |
16 | {searchResultsData.items.map(function(item, i) {
17 | return
18 | })}
19 |
20 |
21 |
22 | );
23 | }
24 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | module.exports = class extends React.Component {
4 | render() {
5 | return (
6 |
480 | );
481 | }
482 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/components/SearchResultsItem.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | module.exports = class extends React.Component {
4 | constructor(props) {
5 | super(props);
6 |
7 | this.state = {
8 | purchased: false,
9 | item: this.props.item
10 | };
11 |
12 | this.handleBuyButtonClick = this.handleBuyButtonClick.bind(this);
13 | }
14 |
15 | componentWillReceiveProps(props) {
16 | this.setState({
17 | purchased: false
18 | });
19 | }
20 |
21 | handleBuyButtonClick() {
22 | this.setState({ 'purchased': true });
23 | }
24 |
25 | render() {
26 | var item = this.props.item;
27 | var style = { backgroundColor: this.state.purchased ? '#f1c40f' : ''};
28 |
29 | return (
30 |
31 |
{item.title}
32 |
33 |
40 |
41 |
{item.price}
42 |
43 | {this.state.purchased ?
44 |
Purchased!
:
45 |
48 | }
49 |
50 |
51 | );
52 | }
53 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender';
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 | $ var renderedHTML = serverRender(App, input.searchResults);
7 |
8 | $!{renderedHTML}
9 |
20 |
23 | @body>
24 |
25 |
--------------------------------------------------------------------------------
/benchmarks/search-results/react/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | browserifyPlugin(envify),
17 | nodeResolvePlugin({
18 | jsnext: true, // Default: false
19 | main: true, // Default: true
20 | browser: true, // Default: false
21 | preferBuiltins: false,
22 | extensions: [ '.js', '.jsx' ]
23 | }),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'react.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/server.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 |
4 | var App = require('./components/App');
5 |
6 | module.exports = function(getNextSearchResults) {
7 | return function benchFn() {
8 | var html = ReactDOMServer.renderToString(
9 | );
10 |
11 | return html;
12 | };
13 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/react/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var ReactDOMServer = require('react-dom/server');
3 |
4 | module.exports = function reactRender(App, searchResultsData) {
5 | return ReactDOMServer.renderToString(
6 | );
7 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('marko/node-require');
3 |
4 | var searchService = require('./util/search');
5 |
6 | module.exports = function(bench) {
7 | var serverFactory = bench.serverFactory;
8 |
9 | var pageIndex = 0;
10 |
11 | function getNextSearchResults() {
12 | return searchService.performSearch({ pageIndex: pageIndex++ });
13 | }
14 |
15 | var fn = serverFactory(getNextSearchResults);
16 |
17 | return {
18 | onWarmup() {
19 | pageIndex = 0;
20 | },
21 | onStart() {
22 | pageIndex = 0;
23 | },
24 | fn
25 | };
26 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/client.js:
--------------------------------------------------------------------------------
1 | import App from './components/App.html';
2 |
3 | var mountNode = document.getElementById("searchResultsMount");
4 |
5 | if (mountNode) {
6 | mountNode.innerHTML = '';
7 |
8 | const app = new App({
9 | target: mountNode,
10 | data: { searchResultsData: window.searchResultsData }
11 | });
12 |
13 | console.log( `window.searchResultsData`, window.searchResultsData )
14 |
15 | console.log('Re-rendering on client completed');
16 | }
17 |
18 | window.addBench('svelte', function(el, getNextSearchResults) {
19 | var widget = new App({
20 | target: el,
21 | data: { searchResultsData: getNextSearchResults() }
22 | });
23 |
24 | return function(done) {
25 | widget.set({
26 | searchResultsData: getNextSearchResults()
27 | });
28 | done();
29 | };
30 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/components/App.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{#each searchResultsData.items as item, i}}
4 |
5 | {{/each}}
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/components/Footer.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/components/SearchResultsItem.html:
--------------------------------------------------------------------------------
1 |
2 |
{{item.title}}
3 |
4 |
11 |
12 |
{{item.price}}
13 |
14 | {{#if purchased}}
15 |
Purchased!
16 | {{else}}
17 |
20 | {{/if}}
21 |
22 |
23 |
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/page.marko:
--------------------------------------------------------------------------------
1 | import 'svelte/ssr/register';
2 | import serverRender from './util/serverRender';
3 | import App from './components/App.html';
4 |
5 |
6 | <@body>
7 |
8 | $ serverRender(App, input.searchResults, out);
9 |
10 |
13 | @body>
14 |
15 |
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/rollup.config.js:
--------------------------------------------------------------------------------
1 | import bublePlugin from 'rollup-plugin-buble';
2 | import sveltePlugin from 'rollup-plugin-svelte';
3 | import path from 'path';
4 |
5 | export default {
6 | entry: path.join(__dirname, 'client.js'),
7 | format: 'iife',
8 | moduleName: 'app',
9 | plugins: [
10 | sveltePlugin(),
11 | bublePlugin()
12 | ],
13 | dest: path.join(process.env.BUNDLES_DIR, 'svelte.js')
14 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/server.js:
--------------------------------------------------------------------------------
1 | require('svelte/ssr/register');
2 |
3 | var App = require('./components/App.html');
4 |
5 | module.exports = function(getNextSearchResults) {
6 | return function benchFn(done) {
7 | const html = App.render({ searchResultsData: getNextSearchResults() });
8 | done();
9 | return html;
10 | };
11 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/svelte/util/serverRender.js:
--------------------------------------------------------------------------------
1 | module.exports = function serverRender(App, searchResultsData, out) {
2 | const html = App.render({ searchResultsData });
3 | out.beginAsync().end(html);
4 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/util/search.js:
--------------------------------------------------------------------------------
1 | var searchResultsData = require('./search-results-data.json');
2 |
3 | exports.performSearch = function(input) {
4 | var pageIndex = input.pageIndex || 0;
5 | var pageSize = 100;
6 | var start = pageIndex * pageSize;
7 |
8 | var items = [];
9 |
10 | for (var i=start; i
10 | }
11 | });
12 |
13 | app.$mount('#searchResultsMount');
14 |
15 | console.log('Re-rendering on client completed');
16 | }
17 |
18 | window.addBench('vue', function(el, getNextSearchResults) {
19 | const app = new Vue({
20 | data: {
21 | searchResultsData: getNextSearchResults()
22 | },
23 |
24 | render(h) {
25 | var searchResultsData = this.searchResultsData;
26 |
27 | return
28 | },
29 |
30 | methods: {
31 | updateSearchResults(searchResultsData, done) {
32 | this.searchResultsData = searchResultsData;
33 | this.$nextTick(done);
34 | }
35 | }
36 | });
37 |
38 | app.$mount(el);
39 |
40 | return function(done) {
41 | app.updateSearchResults(getNextSearchResults(), done);
42 | };
43 | });
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/components/App.jsx:
--------------------------------------------------------------------------------
1 | var Vue = require('vue');
2 | var SearchResultsItem = require('./SearchResultsItem');
3 | var Footer = require('./Footer');
4 |
5 | module.exports = {
6 | mounted() {
7 | window.onMount();
8 | },
9 | props: ['searchResultsData'],
10 | render(h) {
11 | var searchResultsData = this.searchResultsData;
12 |
13 | return (
14 |
15 |
16 | {searchResultsData.items.map(function(item, i) {
17 | return
18 | })}
19 |
20 |
21 |
22 | );
23 | }
24 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | var Vue = require('vue');
2 |
3 | module.exports = {
4 | render(h) {
5 | return (
6 |
480 | );
481 | }
482 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/components/SearchResultsItem.jsx:
--------------------------------------------------------------------------------
1 | var Vue = require('vue');
2 |
3 | module.exports = {
4 | methods: {
5 | handleBuyButtonClick: function(instance) {
6 | this.purchased = true;
7 | }
8 | },
9 | props: ['item', 'purchased'],
10 | render(h) {
11 | var item = this.item;
12 | var purchased = this.purchased;
13 | var style = { backgroundColor: this.purchased ? '#f1c40f' : ''};
14 | var handleBuyButtonClick = this.handleBuyButtonClick;
15 |
16 | return (
17 |
18 |
{item.title}
19 |
20 |
27 |
28 |
{item.price}
29 |
30 | {purchased ?
31 |
Purchased!
:
32 |
35 | }
36 |
37 |
38 | );
39 | }
40 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/page.marko:
--------------------------------------------------------------------------------
1 | import serverRender from './util/serverRender'
2 | import App from './components/App';
3 |
4 |
5 | <@body>
6 |
7 | $ serverRender(App, input.searchResults, out);
8 |
9 |
12 | @body>
13 |
14 |
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjsPlugin from 'rollup-plugin-commonjs';
2 | import browserifyPlugin from 'rollup-plugin-browserify-transform';
3 | import nodeResolvePlugin from 'rollup-plugin-node-resolve';
4 | import babelPlugin from 'rollup-plugin-babel';
5 | import envify from 'envify';
6 | import path from 'path';
7 |
8 | export default {
9 | entry: path.join(__dirname, 'client.jsx'),
10 | format: 'iife',
11 | moduleName: 'app',
12 | plugins: [
13 | babelPlugin({
14 | exclude: 'node_modules/**'
15 | }),
16 | nodeResolvePlugin({
17 | jsnext: false, // Default: false
18 | main: true, // Default: true
19 | browser: true, // Default: false
20 | preferBuiltins: false,
21 | extensions: [ '.js', '.jsx' ]
22 | }),
23 | // browserifyPlugin(envify),
24 | commonjsPlugin({
25 | include: [ 'node_modules/**', '**/*.js', '**/*.jsx'],
26 | extensions: [ '.js', '.jsx' ]
27 | })
28 | ],
29 | dest: path.join(process.env.BUNDLES_DIR, 'vue.js')
30 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/server.jsx:
--------------------------------------------------------------------------------
1 | const Vue = require('Vue');
2 | const renderToString = require('vue-server-renderer').createRenderer().renderToString;
3 |
4 |
5 | var App = require('./components/App');
6 |
7 | module.exports = function(getNextSearchResults) {
8 | return function benchFn(done) {
9 |
10 | const vm = new Vue({
11 | render(h) {
12 | return
13 | }
14 | });
15 |
16 | renderToString(vm, function(err, html) {
17 | if (err) {
18 | throw err;
19 | }
20 |
21 | done();
22 |
23 | return html;
24 | });
25 | };
26 | };
--------------------------------------------------------------------------------
/benchmarks/search-results/vue/util/serverRender.jsx:
--------------------------------------------------------------------------------
1 | const Vue = require('Vue');
2 | const renderToString = require('vue-server-renderer').createRenderer().renderToString;
3 |
4 | module.exports = function serverRender(App, searchResultsData, out) {
5 | const vm = new Vue({
6 | render(h) {
7 | return
8 | }
9 | });
10 |
11 | var asyncOut = out.beginAsync();
12 |
13 | return renderToString(vm, function(err, html) {
14 | if (err) {
15 | throw err;
16 | }
17 |
18 | asyncOut.end(html);
19 | });
20 | };
--------------------------------------------------------------------------------
/images/test-image-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-01.jpg
--------------------------------------------------------------------------------
/images/test-image-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-02.jpg
--------------------------------------------------------------------------------
/images/test-image-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-03.jpg
--------------------------------------------------------------------------------
/images/test-image-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-04.jpg
--------------------------------------------------------------------------------
/images/test-image-05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-05.jpg
--------------------------------------------------------------------------------
/images/test-image-06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sveltejs/isomorphic-ui-benchmarks/066bb85a0194ae31352d3d19a69df7b5366656f9/images/test-image-06.jpg
--------------------------------------------------------------------------------
/index.marko:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Isomorphic UI Benchmarks
6 |
7 |
8 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/init.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 |
3 | if (!process.env.NODE_ENV) {
4 | process.env.NODE_ENV = 'production';
5 | }
6 |
7 | var isProduction = process.env.NODE_ENV === 'production';
8 |
9 | require('lasso').configure({
10 | plugins: [
11 | {
12 | plugin: 'lasso-marko',
13 | config: {
14 | output: 'vdom'
15 | }
16 | },
17 | {
18 | plugin: 'minprops/lasso',
19 | enabled: isProduction
20 | }
21 | ],
22 | bundlingEnabled: false,
23 | minify: false,//isProduction ? true : false,
24 | fingerprintsEnabled: false,
25 | outputDir: path.join(__dirname, 'build/static')
26 | });
27 |
28 | require('require-self-ref');
29 | require('lasso/node-require-no-op').enable('.less', '.css');
30 | require('marko/express');
31 | require("babel-register")({
32 | // and .js so you'll have to add them back if you want them to be used again.
33 | extensions: [".jsx"]
34 | });
35 |
36 | require('marko/node-require').install();
37 | // require('lasso/node-require-no-op').enable('.less', '.css');
38 |
39 | require('marko/compiler').configure({
40 | assumeUpToDate: false
41 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "isomorphic-ui-benchmarks",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "./server.js",
6 | "scripts": {
7 | "test": "npm run benchmark",
8 | "start": "node server.js",
9 | "benchmark": "node --expose-gc benchmark-server/run.js",
10 | "build": "npm run bundle --silent && npm run minify --silent",
11 | "bundle": "node ./scripts/bundle.js",
12 | "minify": "node ./scripts/minify.js",
13 | "build-inferno": "npm run bundle-inferno --silent && node ./scripts/minify.js inferno",
14 | "build-marko": "npm run bundle-marko --silent && node ./scripts/minify.js marko",
15 | "build-svelte": "npm run bundle-svelte --silent && node ./scripts/minify.js svelte",
16 | "build-vue": "npm run bundle-vue --silent && node ./scripts/minify.js vue",
17 | "bundle-inferno": "node ./scripts/bundle.js inferno",
18 | "bundle-marko": "node ./scripts/bundle.js marko",
19 | "bundle-react": "node ./scripts/bundle.js react",
20 | "bundle-preact": "node ./scripts/bundle.js preact",
21 | "bundle-svelte": "node ./scripts/bundle.js svelte",
22 | "bundle-vue": "node ./scripts/bundle.js vue"
23 | },
24 | "author": "Patrick Steele-Idem {
10 | var benchmarkName = benchmark.name;
11 |
12 | benchmark.benches.forEach((bench) => {
13 | var libName = bench.name;
14 | if (targetLib && libName !== targetLib) {
15 | return;
16 | }
17 |
18 | process.env.BUNDLES_DIR = path.join(__dirname, `../build/${benchmarkName}/bundles/`);
19 | execSync(`rollup -c ${bench.dir}/rollup.config.js`);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/scripts/minify.js:
--------------------------------------------------------------------------------
1 | console.log('Minifying JavaScript bundles...');
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const zlib = require('zlib');
6 | const UglifyJS = require("uglify-js");
7 | const formatNumber = require('format-number')();
8 | const mkdirp = require('mkdirp');
9 | const outputDir = path.join(__dirname, '../build');
10 |
11 | function getVersion(name) {
12 | return require(name + '/package.json').version;
13 | }
14 |
15 | function leftPad(str, padding) {
16 | if (str.length < padding) {
17 | str = new Array(padding - str.length).join(' ') + str;
18 | }
19 |
20 | return str;
21 | }
22 |
23 | var minifiers = {
24 | gcc: function minifyGCC(src, file) {
25 | const gcc = require('google-closure-compiler-js');
26 | const options = {
27 | jsCode: [{src: src}],
28 | languageIn: 'ES5'
29 | };
30 |
31 | const out = gcc.compile(options);
32 |
33 | // if (out.errors && out.errors.length) {
34 | // console.error(out.errors);
35 | // throw new Error(`Minification failed for ${file}`);
36 | // }
37 | return out.compiledCode;
38 | },
39 | uglify: function minifyUglifyJS(src, file) {
40 | try {
41 | return UglifyJS.minify(src, {
42 | fromString: true
43 | }).code;
44 | } catch(e) {
45 | if (e.line != null) {
46 | console.error(`Failed to minify ${file}`);
47 | console.error(` Location: ${file}:${e.line}:${e.col}`);
48 | console.error(` Message: ${e.message}`);
49 | process.exit(1);
50 | }
51 | throw e;
52 | }
53 |
54 | },
55 | both: function(src, file) {
56 | var withGCC = minifiers.gcc(src, file);
57 | var withBoth = minifiers.uglify(withGCC, file);
58 | return withBoth.length < withGCC.length ? withBoth : withGCC;
59 | }
60 | };
61 |
62 | var minifier = minifiers.both;
63 |
64 | var targetLib = process.argv[2];
65 |
66 | var promiseChain = Promise.resolve();
67 | var benchmarkBuildDirs = fs.readdirSync(outputDir);
68 |
69 | benchmarkBuildDirs.forEach((benchmarkName) => {
70 | if (benchmarkName === 'static') {
71 | return;
72 | }
73 |
74 | var bundlesOutputDir = path.join(outputDir, benchmarkName, 'bundles');
75 | var bundlesMinOutputDir = path.join(outputDir, benchmarkName, 'bundles.min');
76 | var sizes = {};
77 |
78 | try {
79 | mkdirp.sync(bundlesMinOutputDir);
80 | } catch(e) {}
81 |
82 |
83 | var bundleFiles = fs.readdirSync(bundlesOutputDir);
84 |
85 | bundleFiles.forEach((filename) => {
86 | if (!filename.endsWith('.js')) {
87 | return;
88 | }
89 |
90 | var file = path.join(bundlesOutputDir, filename);
91 | var ext = path.extname(filename);
92 | var lib = filename.slice(0, 0-ext.length);
93 |
94 | if (targetLib && lib !== targetLib) {
95 | return;
96 | }
97 |
98 | console.log(`Minifying ${file}...`);
99 |
100 | var src = fs.readFileSync(file, { encoding: 'utf8' });
101 |
102 | var minifiedSrc = minifier(src, file);
103 |
104 | console.log(`Done minifying ${file}`);
105 |
106 | var minFile = path.join(bundlesMinOutputDir, filename);
107 | fs.writeFileSync(minFile, minifiedSrc, { encoding: 'utf8' });
108 |
109 | var sizeInfo = sizes[lib] = {};
110 |
111 | promiseChain = promiseChain.then(() => {
112 | return new Promise((resolve, reject) => {
113 | console.log(`Compressing and calculating size of ${file}...`);
114 | zlib.gzip(minifiedSrc, function(err, gzippedBuffer) {
115 | if (err) {
116 | return reject(err);
117 | }
118 |
119 | // Compare the sizes
120 | var minifiedBuffer = new Buffer(minifiedSrc, 'utf8');
121 | // console.log(nodePath.basename(templateInfo.outputCompileMinifiedFile) + ': ' + gzippedBuffer.length + ' bytes gzipped (' + minifiedBuffer.length + ' bytes uncompressed)');
122 |
123 | sizeInfo.gzipped = gzippedBuffer.length;
124 | sizeInfo.min = minifiedBuffer.length;
125 |
126 | var libVersion = getVersion(lib);
127 | var sizeFilename = lib + (libVersion ? '-' + libVersion : '') + '.json';
128 |
129 | fs.writeFileSync(path.join(outputDir, benchmarkName, sizeFilename), JSON.stringify(sizeInfo, null, 4), { encoding: 'utf8' });
130 |
131 | resolve();
132 | });
133 | });
134 | });
135 | });
136 |
137 | promiseChain.then(() => {
138 | console.log();
139 |
140 | for (var lib in sizes) {
141 | var sizeInfo = sizes[lib];
142 | console.log('[' + lib + ']');
143 | console.log(' gzip: ' + leftPad(formatNumber(sizeInfo.gzipped), 8) + ' bytes');
144 | console.log(' min: ' + leftPad(formatNumber(sizeInfo.min), 8) + ' bytes');
145 | console.log();
146 | }
147 |
148 | console.log('Minification complete.');
149 | });
150 | });
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | require('./init');
2 |
3 | var express = require('express');
4 | var serveStatic = require('serve-static');
5 | var path = require('path');
6 | var compression = require('compression');
7 | var benchmarks = require('./benchmarks');
8 | var benchmarkClientCreateRoute = require('./benchmark-client/createRoute');
9 | var indexTemplate = require('./index.marko');
10 |
11 | var isProduction = false;//process.env.NODE_ENV === 'production';
12 | var minify = isProduction;
13 |
14 | var app = express();
15 | app.use(compression());
16 |
17 | benchmarks.forEach((benchmark) => {
18 | var benchmarkName = benchmark.name;
19 |
20 | benchmark.benches.forEach((bench) => {
21 | var libName = bench.name;
22 | var jsBundle = `/build/${benchmarkName}/bundles${minify ? '.min' : ''}/${libName}.js`;
23 |
24 | var routeOptions = {
25 | jsBundle: jsBundle
26 | };
27 |
28 | app.get(`/${benchmarkName}/${libName}`, benchmark.createRoute(libName, routeOptions));
29 | app.get(`/benchmark/${benchmarkName}`, benchmarkClientCreateRoute(benchmark, routeOptions));
30 | });
31 | });
32 |
33 | app.use(require('lasso/middleware').serveStatic());
34 |
35 | // app.get('/react', require('./src/react/pages/search-results'));
36 | app.use('/build', serveStatic(path.join(__dirname, 'build')));
37 | app.use('/static', serveStatic(path.join(__dirname, 'static')));
38 | app.use('/images', serveStatic(path.join(__dirname, 'images')));
39 | app.use('/benchmarks', serveStatic(path.join(__dirname, 'benchmarks')));
40 | app.get('/', function(req, res) {
41 | res.marko(indexTemplate, {
42 | benchmarks
43 | });
44 | });
45 | // app.get('/', require('./src/shared/pages/index'));
46 |
47 | var port = process.env.PORT ? parseInt(process.env.PORT, 10) : 8080;
48 |
49 | app.listen(port, function(err) {
50 | if (err) {
51 | throw err;
52 | }
53 |
54 | console.log('Listening on port ' + port);
55 |
56 | if (process.send) {
57 | console.log('Server online');
58 | process.send('online'); // Let browser-refresh know we are ready to serve traffic
59 | }
60 | });
61 |
62 | process.on('SIGTERM', function() {
63 | process.exit(0);
64 | });
--------------------------------------------------------------------------------
/util/runBenchmark.js:
--------------------------------------------------------------------------------
1 | var EventEmitter = require('events').EventEmitter;
2 |
3 | function addListeners(eventEmitter, config) {
4 | Object.keys(config).forEach(function(name) {
5 | if (name.startsWith('on')) {
6 | var listener = config[name];
7 | var eventName = name.charAt(2).toLowerCase() + name.substring(3);
8 | eventEmitter.on(eventName, listener);
9 | }
10 | });
11 | }
12 |
13 | function delay(durationMillis) {
14 | return new Promise(function(resolve, reject) {
15 | setTimeout(resolve, durationMillis);
16 | });
17 | }
18 |
19 |
20 | module.exports = function runBenchmark(name, options, Benchmark) {
21 | var Suite = Benchmark.Suite;
22 | var suite = new Suite(name);
23 |
24 |
25 | var benches = [];
26 |
27 | var suiteEvents = new EventEmitter();
28 | var userSetup;
29 |
30 | function load() {
31 | return Promise.resolve()
32 | .then(function() {
33 | if (typeof options === 'function') {
34 | return options();
35 | } else {
36 | return options;
37 | }
38 | })
39 | .then(function(options) {
40 | addListeners(suiteEvents, options);
41 |
42 | var benchPromiseChain = Promise.resolve();
43 |
44 | Object.keys(options.benches).forEach(function(name) {
45 | benchPromiseChain = benchPromiseChain.then(function() {
46 | var bench = options.benches[name];
47 | if (typeof bench === 'function') {
48 | return bench(name);
49 | } else {
50 | return bench;
51 | }
52 | })
53 | .then(function(bench) {
54 | var benchFn = bench.fn;
55 | userSetup = bench.setup;
56 |
57 | var benchEvents = new EventEmitter();
58 |
59 | addListeners(benchEvents, bench);
60 |
61 | var actualFn;
62 |
63 | var defer = benchFn.length === 1;
64 |
65 | if (defer) {
66 | actualFn = function(deferred) {
67 | function done() {
68 | deferred.resolve();
69 | }
70 |
71 | benchFn(done);
72 | };
73 | } else {
74 | actualFn = function(deferred) {
75 | benchFn();
76 | };
77 | }
78 |
79 | bench = Object.assign({name: name}, bench);
80 | bench.events = benchEvents;
81 |
82 | suite.add(name, {
83 | // a flag to indicate the benchmark is deferred
84 | defer: defer,
85 | // benchmark test function
86 | fn: actualFn,
87 |
88 | onStart: function() {
89 | benchEvents.emit('start');
90 | suiteEvents.emit('startBench', bench);
91 | }
92 | });
93 |
94 | benches.push(bench);
95 | });
96 | });
97 |
98 | return benchPromiseChain;
99 | });
100 | }
101 |
102 | function setup() {
103 | var promiseChain = Promise.resolve();
104 |
105 | if (userSetup) {
106 | promiseChain = promiseChain.then(userSetup);
107 | }
108 |
109 | benches.forEach(function(bench) {
110 | if (bench.setup) {
111 | promiseChain = promiseChain.then(function() {
112 | bench.setup();
113 | });
114 | }
115 | });
116 |
117 | return promiseChain;
118 | }
119 |
120 | function warmupCycle() {
121 | var promiseChain = Promise.resolve();
122 | benches.forEach(function(bench) {
123 | var benchFn = bench.fn;
124 | promiseChain = promiseChain.then(function() {
125 | if (benchFn.length === 1) {
126 | return new Promise(function(resolve, reject) {
127 | benchFn(resolve);
128 | });
129 | } else {
130 | benchFn();
131 | }
132 | });
133 | });
134 |
135 | return promiseChain;
136 | }
137 |
138 | function warmup() {
139 | suiteEvents.emit('warmup');
140 |
141 | benches.forEach(function(bench) {
142 | bench.events.emit('warmup');
143 | });
144 |
145 | var index = 0;
146 | var totalCount = 100;
147 |
148 | function next() {
149 | return warmupCycle()
150 | .then(function() {
151 | if (++index === totalCount) {
152 | suiteEvents.emit('warmupComplete');
153 | return delay(1000);
154 | } else {
155 | return delay(10).then(next);
156 | }
157 | });
158 | }
159 |
160 | return next();
161 | }
162 |
163 | function run() {
164 | return new Promise(function(resolve, reject) {
165 | suite
166 | .on('start', function(event) {
167 | suiteEvents.emit('start', {
168 | suite: suite
169 | });
170 | })
171 | .on('cycle', function(event) {
172 | suiteEvents.emit('cycle', {
173 | suite: suite,
174 | resultsString: String(event.target)
175 | });
176 | })
177 | .on('complete', function() {
178 | suiteEvents.emit('complete', {
179 | suite: suite,
180 | resultsString: 'Fastest is ' + this.filter('fastest').map('name') + '\n\n--------------\n'
181 | });
182 |
183 | suite.off('start cycle complete');
184 | resolve();
185 | })
186 | .on('error', function(e) {
187 | suite.off('start cycle complete error');
188 | reject(e.target.error);
189 | })
190 | .run({ 'async': true });
191 | });
192 | }
193 |
194 | return {
195 | on: function(eventName, listener) {
196 | suiteEvents.on(eventName, listener);
197 | return this;
198 | },
199 |
200 | run: function() {
201 | return Promise.resolve()
202 | .then(load)
203 | .then(setup)
204 | .then(warmup)
205 | .then(run);
206 | }
207 | };
208 | };
--------------------------------------------------------------------------------