Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
16d9ba3
Add fast timeline so far just bidirectional fetching
GiantRobots Jun 16, 2026
1bffd0a
Single start call
GiantRobots Jun 16, 2026
d7af473
Dang that's a lot of events
GiantRobots Jun 17, 2026
093d5ee
First round of optimizations
GiantRobots Jun 17, 2026
ece41ef
Dang knocked 2s off, that's nice.
GiantRobots Jun 17, 2026
1db4c27
More perf fixes
GiantRobots Jun 17, 2026
f54d127
Fix click taking so long (removes push down effect) forgot to add ico…
GiantRobots Jun 17, 2026
5b49aed
Inline the details pane again
GiantRobots Jun 17, 2026
4805e8a
Fix rendering details by making codeblocks render async and using pre…
GiantRobots Jun 17, 2026
65eeca3
Do a swap on Y position for rendering
GiantRobots Jun 17, 2026
56a07bd
Fasterer
GiantRobots Jun 17, 2026
570f79b
Second loading indicator
GiantRobots Jun 17, 2026
2b53a86
Dagnabbit
GiantRobots Jun 17, 2026
1c25823
Partial rendering and full batching
GiantRobots Jun 17, 2026
444f907
Fix this so it packs properly
GiantRobots Jun 17, 2026
120f491
Better timers, more loading
GiantRobots Jun 18, 2026
c926a2a
Oh this works better now
GiantRobots Jun 18, 2026
46efe7f
tests for positioning and first and last page rendering first then wa…
GiantRobots Jun 18, 2026
4fb16e7
better loading
GiantRobots Jun 18, 2026
7a4fa2b
Fix ascending descending showing up first/last. etc
GiantRobots Jun 18, 2026
893bf36
Loading lookin dope
GiantRobots Jun 18, 2026
254b108
perf: replace EventGroup Map+Set with a flat eventList array
GiantRobots Jun 18, 2026
c7b8cbe
perf: O(1) group lookups, eager classification flags, and cheaper las…
GiantRobots Jun 18, 2026
1e3bd96
Fix showing result not showing until dataset is loaded
GiantRobots Jun 18, 2026
a793ae8
Add a memory test for the workflow history objects stuff
GiantRobots Jun 18, 2026
91cda92
Break out fasterer to it's own section, give it it's own stats. Some …
GiantRobots Jun 18, 2026
56b8f6a
Fasterer
GiantRobots Jun 18, 2026
3e71302
Implemented pixi renderer
GiantRobots Jun 19, 2026
8213ce2
Fix gutters
GiantRobots Jun 19, 2026
e46b4bd
lots of sizing and icon stuff
GiantRobots Jun 19, 2026
f61b97c
Gutter tests and icon stuff
GiantRobots Jun 19, 2026
4de183d
Viewport clamping
GiantRobots Jun 20, 2026
483b3b9
Working pretty okay now
GiantRobots Jun 21, 2026
a4fd8a4
Oh man the gutters are working correctly FINALLY
GiantRobots Jun 21, 2026
12e376d
gutters, scrolling etc.
GiantRobots Jun 21, 2026
aa57747
tests and scrolling and such
GiantRobots Jun 22, 2026
e1c15a1
Perf events
GiantRobots Jun 22, 2026
8adea82
sumpin
GiantRobots Jun 23, 2026
573c1a8
perf(pixi-timeline): keyboard nav, rendering optimisations, frame-tim…
GiantRobots Jun 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"serve:playwright:e2e": "vite build && vite preview --mode test.e2e",
"serve:playwright:integration": "vite build && vite preview --mode test.integration --port 3333",
"test": "TZ=UTC vitest",
"test:mem": "TZ=UTC NODE_OPTIONS=--expose-gc vitest run grouped-event-buffer",
"test:ui": "TZ=UTC vitest --ui",
"test:coverage": "TZ=UTC vitest run --coverage",
"test:e2e": "PW_MODE=e2e playwright test tests/e2e",
Expand Down Expand Up @@ -65,6 +66,8 @@
"stylelint:fix": "stylelint --fix \"src/**/*.{css,postcss,svelte}\"",
"generate:locales": "esno scripts/generate-locales.ts",
"run-workflows": "esno scripts/run-workflows.ts",
"perf:signals": "esno scripts/perf-signals.ts",
"perf:events": "esno scripts/perf-events.ts",
"audit:tailwind": "esno scripts/audit-tailwind-colors",
"audit:holocene-props": "esno scripts/generate-holocene-props.ts",
"validate:versions": "./scripts/validate-versions.sh",
Expand Down Expand Up @@ -104,6 +107,7 @@
"kebab-case": "^1.0.2",
"mdast-util-from-markdown": "^2.0.1",
"mdast-util-to-hast": "^13.2.0",
"pixi.js": "^8.19.0",
"remark-stringify": "^10.0.3",
"sveltekit-superforms": "^2.27.4",
"tailwind-merge": "^1.14.0",
Expand Down
73 changes: 73 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

113 changes: 113 additions & 0 deletions scripts/perf-events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Performance test: run HighVolumeEventWorkflow which generates a mixed
* history of activities, timers, child workflows, and signals.
*
* Usage:
* pnpm perf:events # 40 000 target events
* pnpm perf:events --target 10000 # custom target
* pnpm perf:events --no-worker # use already-running worker
*/

import yargs from 'yargs/yargs';

import { connect } from '../temporal/client';
import { runWorker, stopWorker } from '../temporal/worker';
import { HighVolumeEventWorkflow } from '../temporal/workflows';

const argv = await yargs(process.argv.slice(2))
.option('target', {
type: 'number',
default: 40_000,
describe: 'Target history event count',
})
.option('worker', {
type: 'boolean',
default: true,
describe: 'Start embedded Temporal worker',
})
.parse();

const TARGET: number = argv.target;
const WORKFLOW_ID = `perf-events-${Date.now()}`;

async function main() {
console.log('\nπŸš€ Temporal mixed-event perf test');
console.log(` Target events : ${TARGET.toLocaleString()}`);
console.log(
' Mix : activities Β· timers Β· child workflows Β· signals',
);
console.log(` Workflow : ${WORKFLOW_ID}\n`);

if (argv.worker) {
console.log('⏳ Starting embedded worker...');
await runWorker();
}

const client = await connect();

console.log('⏳ Starting HighVolumeEventWorkflow...');
const handle = await client.workflow.start(HighVolumeEventWorkflow, {
taskQueue: 'e2e-1',
workflowId: WORKFLOW_ID,
args: [TARGET],
});

console.log(`βœ… Workflow started: ${handle.workflowId}`);
console.log(
`\nβš™οΈ Generating ${TARGET.toLocaleString()} history events...\n`,
);

const startMs = performance.now();
let lastLogMs = startMs;
let lastCount = 0;

const poller = setInterval(async () => {
try {
const desc = await client.workflow.describe(WORKFLOW_ID);
const count = desc.historyLength ?? 0;
const now = performance.now();
const elapsed = ((now - startMs) / 1000).toFixed(1);
const rate = Math.round((count - lastCount) / ((now - lastLogMs) / 1000));
const pct = Math.min(100, Math.round((count / TARGET) * 100));
console.log(
` [${elapsed}s] ${count.toLocaleString()} / ${TARGET.toLocaleString()} events (${pct}%) Β· ${rate.toLocaleString()} ev/s`,
);
lastLogMs = now;
lastCount = count;
} catch {
// workflow may not be describable yet
}
}, 3000);

const result = await handle.result();
clearInterval(poller);

const totalMs = performance.now() - startMs;

console.log(`\nβœ… Done in ${(totalMs / 1000).toFixed(1)}s`);
console.log('\nπŸ“Š Workflow result:');
console.log(` History events : ${result.historyLength.toLocaleString()}`);
console.log(` Activities : ${result.activities.toLocaleString()}`);
console.log(` Timers : ${result.timers.toLocaleString()}`);
console.log(` Child workflows: ${result.children.toLocaleString()}`);
console.log(` Signals recv'd : ${result.signals.toLocaleString()}`);
if (result.durationMs) {
console.log(
` Workflow span : ${(result.durationMs / 1000).toFixed(1)}s`,
);
console.log(
` Event rate : ${Math.round(result.historyLength / (result.durationMs / 1000)).toLocaleString()} ev/s`,
);
}
console.log(`\n Workflow ID: ${WORKFLOW_ID}`);
console.log(' β†’ Load in UI to test fast-history performance\n');

if (argv.worker) {
await stopWorker();
}
}

main().catch((err) => {
console.error(err);
process.exit(1);
});
Loading
Loading