diff --git a/straylight-v0.3.4-keyed/.babelrc b/straylight-v0.3.4-keyed/.babelrc new file mode 100644 index 000000000..b25395073 --- /dev/null +++ b/straylight-v0.3.4-keyed/.babelrc @@ -0,0 +1,3 @@ +{ + "presets" : [ "babel-preset-es2015"] +} diff --git a/straylight-v0.3.4-keyed/index.html b/straylight-v0.3.4-keyed/index.html new file mode 100644 index 000000000..af928bee4 --- /dev/null +++ b/straylight-v0.3.4-keyed/index.html @@ -0,0 +1,13 @@ + + + + + Straylight + + + +
+ + + + diff --git a/straylight-v0.3.4-keyed/package.json b/straylight-v0.3.4-keyed/package.json new file mode 100644 index 000000000..ad4c0edb3 --- /dev/null +++ b/straylight-v0.3.4-keyed/package.json @@ -0,0 +1,25 @@ +{ + "name": "js-framework-benchmark-straylight", + "version": "1.1.1", + "description": "Straylight demo", + "main": "index.js", + "scripts": { + "build-dev": "webpack -w -d", + "build-prod": "webpack -p" + }, + "author": "Stefan Krause", + "license": "Apache-2.0", + "homepage": "https://github.com/krausest/js-framework-benchmark", + "repository": { + "type": "git", + "url": "https://github.com/krausest/js-framework-benchmark.git" + }, + "devDependencies": { + "babel-core": "6.24.1", + "babel-loader": "7.0.0", + "babel-preset-es2015": "6.24.1", + "storelax": "^0.2.4", + "straylight": "^0.3.4", + "webpack": "2.5.1" + } +} diff --git a/straylight-v0.3.4-keyed/src/main.js b/straylight-v0.3.4-keyed/src/main.js new file mode 100644 index 000000000..ac337a52b --- /dev/null +++ b/straylight-v0.3.4-keyed/src/main.js @@ -0,0 +1,95 @@ +import { html, applyTemplate } from 'straylight'; +import { withKeys } from 'straylight/extras'; +import { store, actions } from './store'; + +function onActionClick(e) { + let { action, id } = e.target.dataset; + if (action) { + actions[action](id ? parseInt(id) : undefined); + } +} + +applyTemplate('#main', html` +
+
+
+
+

Straylight

+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + + ${ + store.observable.map(({ data, selected }) => + withKeys(data.map(d => [d.id, html` + + + + + + + `])) + ) + } + +
${d.id} + ${d.label} + + + + +
+ +
+`); diff --git a/straylight-v0.3.4-keyed/src/store.js b/straylight-v0.3.4-keyed/src/store.js new file mode 100644 index 000000000..4c83c11be --- /dev/null +++ b/straylight-v0.3.4-keyed/src/store.js @@ -0,0 +1,150 @@ +import Store from 'storelax'; + +const timer = { + name: null, + startTime: null, + time(name, fn) { + this.start(name); + fn(); + this.stop(); + }, + start(name) { + this.name = name; + this.startTime = performance.now(); + }, + stop() { + if (this.name) { + window.setTimeout(() => { + console.log(`${this.name} took ${performance.now() - this.startTime}`); + this.name = null; + }, 0); + } + }, +}; + +export const store = new Store({ + data: [], + selected: undefined, + id: 1, +}); + +export const actions = { + run() { + timer.time('run', () => { + store.update(({ id }) => { + const obj = buildData(id, 1000); + return { + data: obj.data, + id: obj.id, + selected: undefined, + }; + }); + }); + }, + + add() { + timer.time('add', () => { + store.update(({ id, data }) => { + const obj = buildData(id, 1000); + return { + data: [...data, ...obj.data], + id: obj.id, + }; + }); + }); + }, + + update() { + timer.time('update', () => { + store.update(({ data }) => { + for (let i = 0; i < data.length; i += 10) { + data[i].label = data[i].label + ' !!!'; + } + return { data }; + }); + }); + }, + + select(id) { + timer.time('select', () => { + store.update({ selected: id }); + }); + }, + + delete(id) { + timer.time('delete', () => { + store.update(({ data }) => { + return { data: data.filter(d => d.id != id) }; + }); + }); + }, + + runLots() { + timer.time('runLots', () => { + store.update(({ id, data }) => { + const obj = buildData(id, 10000); + return { + data: obj.data, + id: obj.id, + selected: undefined, + }; + }); + }); + }, + + clear() { + timer.time('clear', () => { + store.update({ + data: [], + selected: undefined, + }); + }); + }, + + swapRows() { + timer.time('swapRows', () => { + store.update(({ data }) => { + if (data.length > 998) { + let temp = data[1]; + data[1] = data[998]; + data[998] = temp; + } + return { data }; + }); + }); + }, +}; + +function random(max) { + return Math.round(Math.random() * 1000) % max; +} + +const adjectives = [ + 'pretty', 'large', 'big', 'small', 'tall', 'short', 'long', 'handsome', 'plain', + 'quaint', 'clean', 'elegant', 'easy', 'angry', 'crazy', 'helpful', 'mushy', 'odd', + 'unsightly', 'adorable', 'important', 'inexpensive', 'cheap', 'expensive', 'fancy', +]; + +const colours = [ + 'red', 'yellow', 'blue', 'green', 'pink', 'brown', 'purple', 'brown', 'white', + 'black', 'orange', +]; + +const nouns = [ + 'table', 'chair', 'house', 'bbq', 'desk', 'car', 'pony', 'cookie', 'sandwich', + 'burger', 'pizza', 'mouse', 'keyboard', +]; + +export function buildData(id, count = 1000) { + let data = []; + for (let i = 0; i < count; i++) { + data.push({ + id: id++, + label: + adjectives[random(adjectives.length)] + ' ' + + colours[random(colours.length)] + ' ' + + nouns[random(nouns.length)], + }); + } + return { data, id }; +} diff --git a/straylight-v0.3.4-keyed/webpack.config.js b/straylight-v0.3.4-keyed/webpack.config.js new file mode 100644 index 000000000..2323d74b6 --- /dev/null +++ b/straylight-v0.3.4-keyed/webpack.config.js @@ -0,0 +1,36 @@ +'use strict'; + +var path = require('path'); + +module.exports = [{ + cache: {}, + module: { + loaders: [ + { + test: /\.js$/, + loader: 'babel-loader' + }, + { + test: /\.css$/, + loader: 'style-loader!css-loader' + } + ], + }, + entry: { + main: './src/main.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js'], + modules: [ + __dirname, + path.resolve(__dirname, 'src'), + 'node_modules' + ], + alias: { + } + } +}]; diff --git a/straylight-v0.3.4-non-keyed/.babelrc b/straylight-v0.3.4-non-keyed/.babelrc new file mode 100755 index 000000000..b25395073 --- /dev/null +++ b/straylight-v0.3.4-non-keyed/.babelrc @@ -0,0 +1,3 @@ +{ + "presets" : [ "babel-preset-es2015"] +} diff --git a/straylight-v0.3.4-non-keyed/index.html b/straylight-v0.3.4-non-keyed/index.html new file mode 100644 index 000000000..af928bee4 --- /dev/null +++ b/straylight-v0.3.4-non-keyed/index.html @@ -0,0 +1,13 @@ + + + + + Straylight + + + +
+ + + + diff --git a/straylight-v0.3.4-non-keyed/package.json b/straylight-v0.3.4-non-keyed/package.json new file mode 100644 index 000000000..ad4c0edb3 --- /dev/null +++ b/straylight-v0.3.4-non-keyed/package.json @@ -0,0 +1,25 @@ +{ + "name": "js-framework-benchmark-straylight", + "version": "1.1.1", + "description": "Straylight demo", + "main": "index.js", + "scripts": { + "build-dev": "webpack -w -d", + "build-prod": "webpack -p" + }, + "author": "Stefan Krause", + "license": "Apache-2.0", + "homepage": "https://github.com/krausest/js-framework-benchmark", + "repository": { + "type": "git", + "url": "https://github.com/krausest/js-framework-benchmark.git" + }, + "devDependencies": { + "babel-core": "6.24.1", + "babel-loader": "7.0.0", + "babel-preset-es2015": "6.24.1", + "storelax": "^0.2.4", + "straylight": "^0.3.4", + "webpack": "2.5.1" + } +} diff --git a/straylight-v0.3.4-non-keyed/src/main.js b/straylight-v0.3.4-non-keyed/src/main.js new file mode 100644 index 000000000..008cd91d5 --- /dev/null +++ b/straylight-v0.3.4-non-keyed/src/main.js @@ -0,0 +1,94 @@ +import { html, applyTemplate } from 'straylight'; +import { store, actions } from './store'; + +function onActionClick(e) { + let { action, id } = e.target.dataset; + if (action) { + actions[action](id ? parseInt(id) : undefined); + } +} + +applyTemplate('#main', html` +
+
+
+
+

Straylight

+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + + ${ + store.observable.map(({ data, selected }) => + data.map(d => html` + + + + + + + `) + ) + } + +
${d.id} + ${d.label} + + + + +
+ +
+`); diff --git a/straylight-v0.3.4-non-keyed/src/store.js b/straylight-v0.3.4-non-keyed/src/store.js new file mode 100644 index 000000000..4c83c11be --- /dev/null +++ b/straylight-v0.3.4-non-keyed/src/store.js @@ -0,0 +1,150 @@ +import Store from 'storelax'; + +const timer = { + name: null, + startTime: null, + time(name, fn) { + this.start(name); + fn(); + this.stop(); + }, + start(name) { + this.name = name; + this.startTime = performance.now(); + }, + stop() { + if (this.name) { + window.setTimeout(() => { + console.log(`${this.name} took ${performance.now() - this.startTime}`); + this.name = null; + }, 0); + } + }, +}; + +export const store = new Store({ + data: [], + selected: undefined, + id: 1, +}); + +export const actions = { + run() { + timer.time('run', () => { + store.update(({ id }) => { + const obj = buildData(id, 1000); + return { + data: obj.data, + id: obj.id, + selected: undefined, + }; + }); + }); + }, + + add() { + timer.time('add', () => { + store.update(({ id, data }) => { + const obj = buildData(id, 1000); + return { + data: [...data, ...obj.data], + id: obj.id, + }; + }); + }); + }, + + update() { + timer.time('update', () => { + store.update(({ data }) => { + for (let i = 0; i < data.length; i += 10) { + data[i].label = data[i].label + ' !!!'; + } + return { data }; + }); + }); + }, + + select(id) { + timer.time('select', () => { + store.update({ selected: id }); + }); + }, + + delete(id) { + timer.time('delete', () => { + store.update(({ data }) => { + return { data: data.filter(d => d.id != id) }; + }); + }); + }, + + runLots() { + timer.time('runLots', () => { + store.update(({ id, data }) => { + const obj = buildData(id, 10000); + return { + data: obj.data, + id: obj.id, + selected: undefined, + }; + }); + }); + }, + + clear() { + timer.time('clear', () => { + store.update({ + data: [], + selected: undefined, + }); + }); + }, + + swapRows() { + timer.time('swapRows', () => { + store.update(({ data }) => { + if (data.length > 998) { + let temp = data[1]; + data[1] = data[998]; + data[998] = temp; + } + return { data }; + }); + }); + }, +}; + +function random(max) { + return Math.round(Math.random() * 1000) % max; +} + +const adjectives = [ + 'pretty', 'large', 'big', 'small', 'tall', 'short', 'long', 'handsome', 'plain', + 'quaint', 'clean', 'elegant', 'easy', 'angry', 'crazy', 'helpful', 'mushy', 'odd', + 'unsightly', 'adorable', 'important', 'inexpensive', 'cheap', 'expensive', 'fancy', +]; + +const colours = [ + 'red', 'yellow', 'blue', 'green', 'pink', 'brown', 'purple', 'brown', 'white', + 'black', 'orange', +]; + +const nouns = [ + 'table', 'chair', 'house', 'bbq', 'desk', 'car', 'pony', 'cookie', 'sandwich', + 'burger', 'pizza', 'mouse', 'keyboard', +]; + +export function buildData(id, count = 1000) { + let data = []; + for (let i = 0; i < count; i++) { + data.push({ + id: id++, + label: + adjectives[random(adjectives.length)] + ' ' + + colours[random(colours.length)] + ' ' + + nouns[random(nouns.length)], + }); + } + return { data, id }; +} diff --git a/straylight-v0.3.4-non-keyed/webpack.config.js b/straylight-v0.3.4-non-keyed/webpack.config.js new file mode 100644 index 000000000..2323d74b6 --- /dev/null +++ b/straylight-v0.3.4-non-keyed/webpack.config.js @@ -0,0 +1,36 @@ +'use strict'; + +var path = require('path'); + +module.exports = [{ + cache: {}, + module: { + loaders: [ + { + test: /\.js$/, + loader: 'babel-loader' + }, + { + test: /\.css$/, + loader: 'style-loader!css-loader' + } + ], + }, + entry: { + main: './src/main.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].js' + }, + resolve: { + extensions: ['.js'], + modules: [ + __dirname, + path.resolve(__dirname, 'src'), + 'node_modules' + ], + alias: { + } + } +}];