├── .babelrc ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .huskyrc ├── .lintstagedrc ├── .prettierignore ├── LICENSE ├── 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 │ └── vue │ │ ├── .babelrc │ │ ├── client.jsx │ │ ├── components │ │ ├── App.jsx │ │ └── App.vue │ │ ├── page.marko │ │ ├── rollup.config.js │ │ ├── server.jsx │ │ ├── util │ │ └── serverRender.jsx │ │ └── webpack.config.js └── 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 │ ├── util │ ├── search-results-data.json │ └── search.js │ └── vue │ ├── .babelrc │ ├── client.jsx │ ├── components │ ├── App.jsx │ ├── App.vue │ ├── Footer.jsx │ ├── Footer.vue │ ├── SearchResultsItem.jsx │ └── SearchResultsItem.vue │ ├── page.marko │ ├── rollup.config.js │ ├── server.jsx │ ├── util │ └── serverRender.jsx │ └── webpack.config.js ├── eslintrc.json ├── index.marko ├── init.js ├── package-lock.json ├── package.json ├── scripts ├── bundle.js ├── minify.js ├── publish.js ├── rollup.js └── static.js ├── server.js ├── static ├── 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 └── styles │ ├── color-picker.css │ └── search-results.css └── util └── runBenchmark.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "loose": true, 7 | "modules": false, 8 | "targets": { 9 | "node": "current", 10 | "browsers": "Last 1 Chrome version, Last 1 Safari version, Last 1 Firefox version" 11 | } 12 | } 13 | ] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | package.json 3 | package-lock.json 4 | node_modules 5 | build 6 | *.marko.js 7 | App.server.js -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es6": true 6 | }, 7 | "extends": ["eslint:recommended", "prettier"], 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "ecmaVersion": 2018, 13 | "sourceType": "module" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.marko.js 2 | /node_modules 3 | /build 4 | /.cache 5 | .DS_Store 6 | npm-debug.log 7 | .idea 8 | /__publish 9 | App.server.js 10 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.js": ["eslint --fix", "prettier --write", "git add"], 3 | "*.{json,md}": ["prettier --write", "git add"] 4 | } 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | package.json 3 | package-lock.json 4 | node_modules 5 | build 6 | *.marko.js 7 | App.server.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 JS Foundation and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # isomorphic-ui-benchmarks 2 | 3 | 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). 4 | 5 | # Current results 6 | 7 | ## Search results 8 | 9 | Search Results Benchmarks 10 | 11 | ## Color picker 12 | 13 | Color Picker Benchmarks 14 | 15 | --- 16 | 17 | Below are the results of a run on October 21, 2019 18 | 19 | Environment: 20 | 21 | - Node.js v10.16.1 22 | - MacBook Pro (13-inch, 2017) 23 | - Processor: 3.5 GHz Intel Core i7 24 | - Memory: 16 GB 2133 MHz LPDDR3 25 | - macOS Mojave: 10.14.6 26 | - Google Chrome Version 77.0.3865.120 (Official Build) (64-bit) 27 | 28 | ## Server-side 29 | 30 | ``` 31 | Warming up... 32 | 33 | Warmup complete. 34 | 35 | Running "search-results"... 36 | 37 | Running benchmark "marko"... 38 | 39 | marko x 6,399 ops/sec ±2.71% (84 runs sampled) 40 | 41 | Running benchmark "preact"... 42 | 43 | preact x 746 ops/sec ±2.88% (81 runs sampled) 44 | 45 | Running benchmark "react"... 46 | 47 | react x 765 ops/sec ±5.02% (72 runs sampled) 48 | 49 | Running benchmark "vue"... 50 | 51 | vue x 2,657 ops/sec ±4.41% (60 runs sampled) 52 | 53 | Running benchmark "inferno"... 54 | 55 | inferno x 3,014 ops/sec ±1.78% (87 runs sampled) 56 | 57 | Fastest is marko 58 | 59 | -------------- 60 | 61 | 62 | Warming up... 63 | 64 | Warmup complete. 65 | 66 | Running "color-picker"... 67 | 68 | Running benchmark "marko"... 69 | 70 | marko x 24,540 ops/sec ±1.48% (86 runs sampled) 71 | 72 | Running benchmark "preact"... 73 | 74 | preact x 4,587 ops/sec ±1.81% (85 runs sampled) 75 | 76 | Running benchmark "react"... 77 | 78 | react x 4,300 ops/sec ±4.72% (72 runs sampled) 79 | 80 | Running benchmark "vue"... 81 | 82 | vue x 9,120 ops/sec ±5.56% (70 runs sampled) 83 | 84 | Running benchmark "inferno"... 85 | 86 | inferno x 21,453 ops/sec ±2.12% (84 runs sampled) 87 | 88 | Fastest is marko 89 | 90 | -------------- 91 | 92 | 93 | DONE! 94 | 95 | ~/marko-js/isomorphic-ui-benchmarks (master)> node -v 96 | v10.16.1 97 | ``` 98 | 99 | # Client-side 100 | 101 | ## Search results 102 | 103 | ### Google Chrome 104 | 105 | ``` 106 | Warming up... 107 | Warmup complete. 108 | Running "search-results"... 109 | Running benchmark "marko"... 110 | marko x 175 ops/sec ±1.84% (53 runs sampled) 111 | Running benchmark "preact"... 112 | preact x 132 ops/sec ±1.66% (48 runs sampled) 113 | Running benchmark "react"... 114 | react x 210 ops/sec ±1.36% (53 runs sampled) 115 | Running benchmark "vue"... 116 | vue x 142 ops/sec ±1.31% (52 runs sampled) 117 | Running benchmark "inferno"... 118 | inferno x 239 ops/sec ±1.24% (55 runs sampled) 119 | Fastest is inferno 120 | ``` 121 | 122 | ## Color picker 123 | 124 | ### Google Chrome 125 | 126 | ``` 127 | Warming up... 128 | Warmup complete. 129 | Running "color-picker"... 130 | Running benchmark "marko"... 131 | marko x 6,008 ops/sec ±1.66% (34 runs sampled) 132 | Running benchmark "preact"... 133 | preact x 6,435 ops/sec ±0.96% (59 runs sampled) 134 | Running benchmark "react"... 135 | react x 7,358 ops/sec ±1.43% (58 runs sampled) 136 | Running benchmark "vue"... 137 | vue x 4,291 ops/sec ±1.96% (55 runs sampled) 138 | Running benchmark "inferno"... 139 | inferno x 17,078 ops/sec ±2.17% (60 runs sampled) 140 | Fastest is inferno 141 | ``` 142 | 143 | # Additional details 144 | 145 | ## Included libraries 146 | 147 | The following UI libraries are currently included: 148 | 149 | - [inferno](https://github.com/infernojs/inferno) 150 | - [marko](https://github.com/marko-js/marko) 151 | - [preact](https://github.com/developit/preact) 152 | - [react](https://github.com/facebook/react) 153 | - [vue](https://github.com/vuejs/vue) 154 | 155 | ## Included benchmarks 156 | 157 | This repo currently includes the following benchmarks 158 | 159 | ### Search Results 160 | 161 | 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. 162 | 163 | ### Color Picker 164 | 165 | 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: 166 | 167 | - The new selected color is highlighted 168 | - The old selected color is unhighlighted 169 | - The selected color is shown at the end 170 | 171 | Compared to the search results benchmark, there are a relatively small number of changes to the DOM for every cycle. 172 | 173 | # Running the benchmarks 174 | 175 | ## Install 176 | 177 | ```bash 178 | git clone https://github.com/marko-js/isomorphic-ui-benchmarks.git 179 | cd isomorphic-ui-benchmarks 180 | npm install 181 | npm run build # Build client-side JS bundles 182 | ``` 183 | 184 | ## Run server-side benchmarks 185 | 186 | ```bash 187 | npm run benchmark 188 | ``` 189 | 190 | ## Run client-side benchmarks 191 | 192 | Start 193 | 194 | ```bash 195 | npm start 196 | ``` 197 | 198 | Open [http://localhost:8080/](http://localhost:8080/) in your browser and choose a benchmark to run. 199 | 200 | # Contributions and Feedback 201 | 202 | 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. 203 | -------------------------------------------------------------------------------- /benchmark-client/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | "lodash/lodash.js", 4 | "benchmark/benchmark.js", 5 | "require: ./components/app" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /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 | } 20 | -------------------------------------------------------------------------------- /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(_, 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() { 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 |
8 |
9 |
10 |
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) { 6 | var bundles = []; 7 | benchmark.benches.forEach(bench => { 8 | bundles.push( 9 | `${process.env.URL_PREFIX || ""}/bundles/${benchmark.name}/${bench.name}${ 10 | isProduction ? ".min" : "" 11 | }.js` 12 | ); 13 | }); 14 | 15 | return function(req, res) { 16 | res.marko(template, { 17 | $global: { 18 | benchmark 19 | }, 20 | bundles 21 | }); 22 | }; 23 | } 24 | 25 | module.exports = createRoute; 26 | -------------------------------------------------------------------------------- /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 8 | .renderSync({ 9 | libName: libName 10 | }) 11 | .appendTo(document.getElementById("mount")) 12 | .getComponent(); 13 | 14 | mountEls[key] = mountedComponent.el; 15 | 16 | return mountedComponent.getEl("output"); 17 | } 18 | 19 | function showSingleMountEl(libName) { 20 | var key = libName; 21 | 22 | for (var curKey in mountEls) { 23 | var mountEl = mountEls[curKey]; 24 | if (curKey === key) { 25 | mountEl.style.display = "inline-block"; 26 | } else { 27 | mountEl.style.display = "none"; 28 | } 29 | } 30 | } 31 | 32 | function showMountEl(libName) { 33 | var key = libName; 34 | 35 | var mountEl = mountEls[key]; 36 | mountEl.style.display = "inline-block"; 37 | } 38 | 39 | exports.createMountEl = createMountEl; 40 | exports.showSingleMountEl = showSingleMountEl; 41 | exports.showMountEl = showMountEl; 42 | -------------------------------------------------------------------------------- /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: " + 8 | require.resolve( 9 | "../benchmarks/" + out.global.benchmark.name + "/client.js" 10 | ) 11 | ]; 12 | 16 | 17 | 18 | 19 | 20 | ${out.global.benchmark.name} | Marko Benchmark 21 | 22 | 27 | 28 | 29 |

${out.global.benchmark.name} | Marko Benchmark

30 | 31 | 34 | 35 | 36 | 37 | 22 | 23 | -------------------------------------------------------------------------------- /benchmarks/color-picker/inferno/rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjsPlugin from "rollup-plugin-commonjs"; 2 | import nodeResolvePlugin from "rollup-plugin-node-resolve"; 3 | import replace from "rollup-plugin-replace"; 4 | import babelPlugin from "rollup-plugin-babel"; 5 | import path from "path"; 6 | 7 | export default { 8 | input: path.join(__dirname, "client.jsx"), 9 | plugins: [ 10 | babelPlugin({ runtimeHelpers: true }), 11 | replace({ "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV) }), 12 | nodeResolvePlugin({ 13 | mainFields: ["browser", "module", "jsnext", "main"], 14 | preferBuiltins: false, 15 | extensions: [".js", ".jsx"] 16 | }), 17 | commonjsPlugin({ 18 | extensions: [".js", ".jsx"] 19 | }) 20 | ], 21 | output: { 22 | name: "app", 23 | format: "iife", 24 | file: path.join(process.env.BUNDLES_DIR, "inferno.js") 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /benchmarks/color-picker/inferno/server.jsx: -------------------------------------------------------------------------------- 1 | var Inferno = require("inferno"); 2 | var createVNode = Inferno.createVNode; 3 | var InfernoServer = require("inferno-server"); 4 | var App = require("./components/App"); 5 | 6 | module.exports = function(colors) { 7 | return function benchFn() { 8 | var html = InfernoServer.renderToString(); 9 | 10 | return html; 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /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 | var component = app 6 | .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 | }); 18 | -------------------------------------------------------------------------------- /benchmarks/color-picker/marko/components/app/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onCreate() { 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 |

Choose your favorite color:

22 | 23 | 24 |
    25 | 26 | $ { 27 | var className = "color"; 28 | if (selectedColorIndex === i) { 29 | className += " selected"; 30 | } 31 | } 32 |
  • 36 | ${color.name} 37 |
  • 38 | 39 |
40 | 41 | 42 |
No colors!
43 |
44 | 45 |
46 | You chose: 47 |
${selectedColor.name}
48 |
49 | 50 | -------------------------------------------------------------------------------- /benchmarks/color-picker/marko/page.marko: -------------------------------------------------------------------------------- 1 | <${input.pageLayout}> 2 | <@body> 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /benchmarks/color-picker/marko/rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjsPlugin from "rollup-plugin-commonjs"; 2 | import nodeResolvePlugin from "rollup-plugin-node-resolve"; 3 | import marko from "@marko/rollup"; 4 | import path from "path"; 5 | 6 | export default { 7 | input: path.join(__dirname, "client.js"), 8 | output: { 9 | name: "app", 10 | format: "iife", 11 | file: path.join(process.env.BUNDLES_DIR, "marko.js") 12 | }, 13 | plugins: [ 14 | marko(), 15 | nodeResolvePlugin({ 16 | mainFields: ["browser", "module", "jsnext", "main"], 17 | preferBuiltins: false, 18 | extensions: [".js", ".marko"] 19 | }), 20 | commonjsPlugin({ 21 | extensions: [".js", ".marko"] 22 | }) 23 | ] 24 | }; 25 | -------------------------------------------------------------------------------- /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 | }; 12 | -------------------------------------------------------------------------------- /benchmarks/color-picker/page.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ${out.global.title} • Isomorphic UI Benchmarks 6 | 10 | 11 | 12 |

${out.global.title} • Isomorphic UI Benchmarks

13 |