Skip to content

Commit

Permalink
Add benchmark app for js-framework-benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
kayahr committed Jan 28, 2025
1 parent aa77292 commit 4b5abe9
Show file tree
Hide file tree
Showing 11 changed files with 447 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .cspell/project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ jsxs
kayahr
lifecycles
multilines
preloadicon
Reimer
runlots
smallpad
swaprows
107 changes: 107 additions & 0 deletions src/demo/benchmark/benchmark.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { For, type JSX, render } from "@kayahr/harmless";
import { arraySignal, atomic, signal, type WritableSignal } from "@kayahr/signal";

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 colors = [ "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" ];

const random = (max: number) => Math.round(Math.random() * 1000) % max;

let nextId = 1;

interface Data {
id: number;
label: WritableSignal<string>;
}

const buildData = (count: number) => {
const data = new Array(count) as Data[];
for (let i = 0; i < count; i++) {
const label = signal(
`${adjectives[random(adjectives.length)]} ${colors[random(colors.length)]} ${nouns[random(nouns.length)]}`
);
data[i] = { id: nextId++, label };
}
return data;
};

const Button = ({ id, children, fn }: { id: string, children: JSX.Element, fn: () => void }) => (
<div class="col-sm-6 smallpad">
<button id={id} class="btn btn-primary btn-block" type="button" onclick={fn}>
{children}
</button>
</div>
);

document.getElementById("main")?.appendChild(render(() => {
const data = arraySignal<Data>([]);
const selected = signal<number | null>(null);
const run = () => data.set(buildData(1_000));
const runLots = () => data.set(buildData(10_000));
const add = () => data.push(...buildData(1_000));
const update = () =>
atomic(() => {
for (let i = 0, d = data(), len = d.length; i < len; i += 10) {
d[i]?.label.update(l => l + " !!!");
}
});
const clear = () => data.set([]);
const swapRows = () => {
if (data.length > 998) {
const item = data.at(1) as Data;
atomic(() => {
data.setAt(1, data.at(998) as Data);
data.setAt(998, item);
});
}
};

return (
<div class="container">
<div class="jumbotron">
<div class="row">
<div class="col-md-6">
<h1>Harmless</h1>
</div>
<div class="col-md-6">
<div class="row">
<Button id="run" fn={run}>Create 1,000 rows</Button>
<Button id="runlots" fn={runLots}>Create 10,000 rows</Button>
<Button id="add" fn={add}>Append 1,000 rows</Button>
<Button id="update" fn={update}>Update every 10th row</Button>
<Button id="clear" fn={clear}>Clear</Button>
<Button id="swaprows" fn={swapRows}>Swap Rows</Button>
</div>
</div>
</div>
</div>
<table class="table table-hover table-striped test-data">
<tbody>
<For each={data}>
{row => {
const rowId = row.id;
return (
<tr class={() => selected() === rowId ? "danger" : ""}>
<td class="col-md-1">{rowId}</td>
<td class="col-md-4">
<a onclick={() => selected.set(rowId)}>{row.label}</a>
</td>
<td class="col-md-1">
<a onclick={() => data.splice(data.findIndex(d => d.id === rowId), 1)}>
<span class="glyphicon glyphicon-remove" aria-hidden="true" />
</a>
</td>
<td class="col-md-6" />
</tr>
);
}}
</For>
</tbody>
</table>
<span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true" />
</div>
);
}));
6 changes: 6 additions & 0 deletions src/demo/benchmark/css/bootstrap/dist/css/bootstrap.min.css

Large diffs are not rendered by default.

Binary file not shown.
Loading

0 comments on commit 4b5abe9

Please sign in to comment.