From 7e1588c45af8ce43e326a5c551f881a14f4f5ff4 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sun, 18 Oct 2026 23:16:53 +0200 Subject: [PATCH] Optimize component host matching and add component-heavy benchmarks --- benchmarks/README.md | 27 ++++- benchmarks/index.html | 17 ++- benchmarks/initial-load.html | 7 ++ benchmarks/minidom/README.md | 28 +++++ benchmarks/minidom/perf-baseline.1000.json | 112 +++++++++++++------ benchmarks/minidom/perf-baseline.2000.json | 112 +++++++++++++------ benchmarks/minidom/perf-baseline.500.json | 110 ++++++++++++------ benchmarks/minidom/perf.ts | 123 ++++++++++++++++++--- benchmarks/src/component-workload.ts | 99 +++++++++++++++++ benchmarks/src/index.ts | 86 +++++++++++--- benchmarks/src/initial-load.ts | 52 +++++++-- benchmarks/src/shared.ts | 5 + benchmarks/tsconfig.json | 8 ++ package.json | 4 +- src/bind/ComponentBinder.ts | 98 ++++++++++------ tests/bind/component-binder-edge.spec.ts | 58 ++++++++++ 16 files changed, 768 insertions(+), 178 deletions(-) create mode 100644 benchmarks/src/component-workload.ts create mode 100644 benchmarks/tsconfig.json diff --git a/benchmarks/README.md b/benchmarks/README.md index 60f2d61..d56c027 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -16,6 +16,25 @@ The benchmark mounts a large bound list and then runs repeated manipulations: Each framework runs the same operation pattern; timings are measured with `performance.now()`. +Use the **Workload** selector to choose the original **Bound list** or +**Nested components (3 per row)**. Both workloads run the same keyed list +operations. The component workload renders a row card, label component, and +value component for each row, with reactive props, class fallthrough, and +parent-scoped slot content. Regor uses an app-local row component, a label +registered in each row's context, and a globally registered value component. +Vue renders the equivalent component tree and DOM. + +At 500 rows this mounts 1,500 component instances; at 2,000 rows it mounts 6,000. +Component definitions are created before mount timing. Regor prepares its +component templates there; Vue's runtime template compilation occurs during +mount. Rendering is checked after mount and each operation, outside the timed +sections. A rendering mismatch fails the run. + +Regor's swap uses batched `splice` calls, shuffle commits the shuffled order +with `splice`, and object replacement updates each existing element ref with +`rows[i](ref(replacements[i]))`. This preserves reactive updates rather than replacing the +ref functions stored at array indexes. + ## Run 1. Build benchmark bundle: @@ -34,11 +53,15 @@ yarn bench:serve `http://localhost:4177/` -4. Click **Run Benchmark**. +4. Select a workload and click **Run Regor**, **Run Vue**, or **Run Both**. + +The mount-only benchmark at `http://localhost:4177/benchmarks/initial-load.html` +has the same workload selector. ## Notes - `Vue@latest` requires internet access. - Run multiple times and compare medians. - Keep browser/devtools conditions consistent for fair comparisons. - +- The Node-based [minidom suite](minidom/README.md) also includes component + mounting, prop updates, and repeated subtree remounting. diff --git a/benchmarks/index.html b/benchmarks/index.html index 9693e27..8f143fc 100644 --- a/benchmarks/index.html +++ b/benchmarks/index.html @@ -15,7 +15,7 @@ } body { margin: 0; - font-family: Consolas, "Courier New", monospace; + font-family: Consolas, 'Courier New', monospace; background: radial-gradient(circle at 0% 0%, #1e293b 0, var(--bg) 45%); color: var(--fg); } @@ -98,12 +98,20 @@

DOM Benchmark: Regor vs Vue (latest)

- Workload: mount a bound list, then run repeated list/data manipulations - (`for` binding updates, splices, push/shift, property updates). + Workload: mount a bound list, then run repeated list/data + manipulations (`for` binding updates, splices, push/shift, property + updates).

+