Docs: Complete Homepage Tour and Showcase#287
Conversation
🟡 Deploying Preview for
|
| project | status | eta | started | build time | logs |
|---|---|---|---|---|---|
docs |
🟡 Building | 10:41 AM | 10:38 AM | ~3m | logs |
mcp |
⚪ NA | — | — | — | — |
Run: #28667323696
⚪ Bundle size: no meaningful change · +5 shipped LOC for
|
| signal | result |
|---|---|
component brotli |
-47 B (-0.1%) |
| Shipped LOC | +5 |
| Comment LOC | -1 |
| Changed bundles | 0 / 24 |
No bundle changed size. 🎉
LOC by scope: +5 shipped LOC · -1 comment LOC
Shipped LOC excludes comments and blank lines.
| scope | shipped LOC | comment LOC |
|---|---|---|
renderer |
+4 | -1 |
design-system |
+1 | +0 |
All 24 bundles, gzip, and raw sizes
| bundle | group | brotli | Δ brotli | gzip | Δ gzip | raw | Δ raw |
|---|---|---|---|---|---|---|---|
compiler |
package | 6.1 KB | — | 6.8 KB | — | 18.4 KB | — |
component 🎯 |
package | 48.6 KB | -47 B | 55.6 KB | +7 B | 169.9 KB | +94 B |
query |
package | 16.0 KB | — | 17.8 KB | — | 52.5 KB | — |
reactivity |
package | 7.1 KB | — | 7.8 KB | — | 22.2 KB | — |
renderer |
package | 43.2 KB | +42 B | 49.2 KB | +32 B | 150.9 KB | +94 B |
specs |
package | 53.9 KB | — | 63.8 KB | — | 236.3 KB | — |
tailwind |
package | 67.3 KB | — | 85.3 KB | — | 335.3 KB | — |
templating |
package | 28.8 KB | — | 32.3 KB | — | 95.9 KB | — |
utils † |
package | 17.6 KB | — | 19.7 KB | — | 50.9 KB | — |
framework |
framework | 129.8 KB | +64 B | 165.7 KB | +12 B | 697.5 KB | +94 B |
button |
primitive | 12.0 KB | — | 15.2 KB | — | 128.6 KB | — |
card |
primitive | 3.0 KB | — | 3.5 KB | — | 15.8 KB | — |
container |
primitive | 694 B | — | 888 B | — | 2.4 KB | — |
divider |
primitive | 1.6 KB | — | 1.9 KB | — | 6.5 KB | — |
icon |
primitive | 26.3 KB | — | 35.0 KB | — | 143.7 KB | — |
image |
primitive | 776 B | — | 993 B | — | 2.2 KB | — |
input |
primitive | 3.9 KB | — | 4.5 KB | — | 15.6 KB | — |
label |
primitive | 1.3 KB | — | 1.6 KB | — | 5.5 KB | — |
menu |
primitive | 14.2 KB | — | 16.3 KB | — | 64.5 KB | — |
modal |
primitive | 1.7 KB | — | 2.0 KB | — | 6.7 KB | — |
rail |
primitive | 534 B | — | 695 B | — | 1.5 KB | — |
segment |
primitive | 3.1 KB | — | 3.7 KB | — | 19.7 KB | — |
spinner |
primitive | 1.8 KB | — | 2.1 KB | — | 8.0 KB | — |
table |
primitive | 555 B | — | 692 B | — | 1.3 KB | — |
brotli q11 · gzip l9 · vs main · fresh build both sides · 53s
⚪ No leak for
|
| invariant | baseline | after 7 cycles | verdict |
|---|---|---|---|
| live `Reaction` | 0 | 0 | ✅ held |
| live `ReactionScope` | 0 | 0 | ✅ held |
| live `DynamicRegion` | 0 | 0 | ✅ held |
| live `Dependency` | 2 | 2 | ✅ held |
| live `Signal` | 2 | 2 | ✅ held |
| detached DOM nodes | 0 | 0 | ✅ held |
🎯 = the leak this PR introduced or fixed. counts are exact — a residual is a real leak, not a sample.
Footprint by scene (post-GC retained heap)
| scene | retained | Δ | |
|---|---|---|---|
create-1k |
4.9 MB | +2 KB | within noise |
create-5k |
14.4 MB | +8 KB | within noise |
Reactivity micro (Node, --expose-gc)
10000 signals + computeds + reactions: 13.8 MB graph heapUsed (+2 KB, 0%, within noise)
residual after teardown + GC: 10.9 MB — a footprint trend, not a gate.
7 cycles · GC ×2/sample · Chrome 149.0.7827.55 (pinned) · counts exact · heap ±4% floor · 1m23s
❌ Regression for
|
| metric | Regression |
|---|---|
dom-walker-1000x15 |
+4% (1ms) |
⚪ No Change (23)
Metrics where this PR measured within ±2% of main — no meaningful performance change detected.
| metric | Change |
|---|---|
todo:add-20 |
-1.3% – +0.8% |
build-html-string-10k |
-1.7% – +0.4% |
todo:bulk-add-500 |
-0.8% – +0.4% |
krausest:clear-10k |
-0.3% – +1.4% |
todo:clear-completed-250 |
-1.5% – +0.6% |
krausest:create-10k |
-0.2% – +0.6% |
krausest:create-1k |
-0.7% – +1.5% |
each-100 |
-0.4% – +1.4% |
each-100-mount |
-1.4% – +0.1% |
template:each-mount-1000 |
-0.6% – +0.9% |
todo:edit-cycle-5 |
-1.8% – +1.3% |
todo:edit-start-10 |
-0.3% – +1.3% |
todo:filter-cycle-20 |
-1.1% – +0.8% |
helper-100-mount |
-0.6% – +1.7% |
todo:remove-50-back |
-1.6% – +1.3% |
todo:remove-last-100 |
-1.4% – +0.9% |
template:snippet-args-per-key-100x500 |
-1.4% – +1.9% |
template:subtemplate-data-blob-100 |
-1.1% – +0.6% |
template:subtemplate-helpers-heavy-100x500 |
-0.5% – +0.6% |
template:subtemplate-reactive-data-100x500 |
-1.5% – +0.8% |
template:subtemplate-shorthand-props-100x500 |
-1.6% – +1.1% |
todo:toggle-all-200 |
-0.5% – +0.1% |
todo:toggle-middle-100 |
-0.3% – +0.9% |
🔍 Unsure (25)
Too Fast to Measure Precisely (25)
On benches this short, OS jitter, GC, and JIT pauses drown out anything under 4%. Bigger changes than that still show up.
| metric | Change | Test Time | Expected Noise |
|---|---|---|---|
template:active-indicator-200 |
-1.0% – +2.6% | ~34ms | ±6% |
template:active-indicator-nested-200 |
-2.4% – +4.1% | ~22ms | ±11% |
krausest:append-1k |
-2.2% – +3.5% | ~86ms | ±7% |
expr-js-10k |
-1.0% – +2.2% | ~19ms | ±8% |
expr-lisp-50k |
-0.7% – +2.2% | ~40ms | ±7% |
expr-simple-100k |
-2.5% – +1.1% | ~23ms | ±9% |
helper-100-state-change-1k |
-0.4% – +3.4% | ~4ms | ±9% |
todo:remove-50-front |
-3.9% – +0.1% | ~7ms | ±4% |
todo:remove-50-middle |
-3.3% – +3.0% | ~7ms | ±8% |
todo:remove-first-100 |
+0.2% – +5.1% | ~14ms | ±6% |
todo:remove-middle-100 |
-3.2% – +5.8% | ~12ms | ±11% |
krausest:remove-row-back-100 |
-3.2% – +2.5% | ~26ms | ±7% |
krausest:remove-row-front-20 |
-2.5% – +4.9% | ~9ms | ±9% |
krausest:remove-row-middle-20 |
-7.8% – +1.5% | ~6ms | ±12% |
todo:rename-500 |
-2.5% – +5.4% | ~18ms | ±10% |
krausest:replace-1k |
-2.2% – +2.0% | ~85ms | ±4% |
krausest:select-40 |
-2.8% – +7.2% | ~6ms | ±12% |
template:snippet-in-subtemplate-100x1k |
-2.6% – +1.3% | ~21ms | ±6% |
template:stable-ref-mutate-500 |
-0.8% – +3.9% | ~14ms | ±7% |
template:subtemplate-helpers-light-100x500 |
-0.7% – +2.1% | ~70ms | ±5% |
krausest:swap-rows-20 |
-5.9% – +1.1% | ~13ms | ±6% |
todo:toggle-100 |
-4.8% – +2.7% | ~13ms | ±10% |
todo:toggle-first-100 |
-0.6% – +5.2% | ~14ms | ±7% |
todo:toggle-last-100 |
-0.7% – +4.4% | ~13ms | ±6% |
krausest:update-10th-50 |
-1.8% – +2.6% | ~27ms | ±6% |
📖 Bench glossary (40 metrics)
| metric | what it tests |
|---|---|
krausest:append-1k |
Appends 1000 new rows onto an existing 1000-row table. |
krausest:clear-10k |
Clears a 10000-row table back to empty in a single operation. |
krausest:create-10k |
Renders a fresh 10000-row table into an empty parent at ten times the create-1k scale. |
krausest:create-1k |
Renders a fresh 1000-row table into an empty parent. |
krausest:remove-row-back-100 |
Removes the last row 100 times from a 1000-row table, with no other rows needing to move. |
krausest:remove-row-front-20 |
Removes the first row 20 times from a 1000-row table, with all remaining rows sliding up each time. |
krausest:remove-row-middle-20 |
Removes the middle row 20 times from a 1000-row table, with the rows below it sliding up each time. |
krausest:replace-1k |
Replaces 1000 rows with a fresh 1000-row set, diffing the keyed list against a populated table. |
krausest:select-40 |
Highlights one row at a time across 40 rows so only the previous and newly highlighted rows update. |
krausest:swap-rows-20 |
Swaps the second and second-to-last rows in a 1000-row table, repeated 20 times. |
krausest:update-10th-50 |
Updates the label on every tenth row of a 1000-row table, looped 50 times to lift the work above noise. |
template:active-indicator-200 |
Cycles selectedId across 200 list items. Only the previously and newly active items update their class. |
template:active-indicator-nested-200 |
Cycles currentUrl through 50 leaf urls in a 5×10×4 nav. Only the previously and newly active leaves should update their… |
template:each-mount-1000 |
Mounts a fresh 1000-item each block with five-field items so per-record allocation cost dominates the wall clock. |
template:snippet-args-per-key-100x500 |
Mutates one snippet arg's source across 100 invocations, 500 cycles. Adjacent no-signal expressions stay quiet. |
template:snippet-in-subtemplate-100x1k |
Mutates one subtemplate prop's source across 25 cards each invoking 4 inner snippets, 1000 cycles. Snippet bodies shoul… |
template:stable-ref-mutate-500 |
Replaces one item by index in a 500-item list across 100 cycles. Only that item's expressions re-render. |
template:subtemplate-data-blob-100 |
Mutates one field inside data=expression on 100 children. Every child re-renders by design. |
template:subtemplate-helpers-heavy-100x500 |
100 subtemplates, 4 inner bindings where three call helpers shaped like userland reality — Intl.NumberFormat, Array.fin… |
template:subtemplate-helpers-light-100x500 |
100 subtemplates, 4 inner bindings each calling formatDate / classIf / capitalize, 500 cycles. Mutates one source signa… |
template:subtemplate-reactive-data-100x500 |
Mutates one verbose reactiveData field across 100 child subtemplates, 500 cycles. Only the changed field re-evaluates. |
template:subtemplate-shorthand-props-100x500 |
Mutates one shorthand prop's source across 100 child subtemplates, 500 cycles. Only that prop re-evaluates. |
todo:add-20 |
Appends 20 todo items one at a time, like a user typing entries in a row. |
todo:bulk-add-500 |
Renders 500 todo items added at once from a single data load. |
todo:clear-completed-250 |
Clears 250 completed items from a 500-item list in one action, like clicking clear completed. |
todo:edit-cycle-5 |
Runs 5 full edit-then-save cycles on different items, like editing a row and saving it. |
todo:edit-start-10 |
Enters edit mode on 10 different items in a row, like double-clicking each one. |
todo:filter-cycle-20 |
Cycles through active, completed, and all filters 20 times on a 100-item list. |
todo:remove-50-back |
Deletes 50 items from the end of a 100-item list, one click at a time. |
todo:remove-50-front |
Deletes 50 items from the front of a 100-item list, one click at a time. |
todo:remove-50-middle |
Deletes 50 items from the middle of a 100-item list, one click at a time. |
todo:remove-first-100 |
Deletes the first item 100 times from a 200-item list, with remaining items moving up each time. |
todo:remove-last-100 |
Deletes the last item 100 times from a 200-item list, with no other items needing to move. |
todo:remove-middle-100 |
Deletes the middle item 100 times from a 200-item list, walking halfway through to find each target. |
todo:rename-500 |
Renames items in a 100-item list 500 times via single-field setProperty without editingId co-fires. |
todo:toggle-100 |
Cycles through the first 10 items 10 times each, like a user toggling items repeatedly down a list. |
todo:toggle-all-200 |
Toggles all 100 items completed and back across 200 cycles via the master checkbox. |
todo:toggle-first-100 |
Toggles the first item in a 100-item list 100 times, alternating completed on and off. |
todo:toggle-last-100 |
Toggles the last item in a 100-item list 100 times, alternating completed on and off. |
todo:toggle-middle-100 |
Toggles a middle item in a 100-item list 100 times, alternating completed on and off. |
Sample size: 80 floor / 280 max · Noise floor: ±2% · Timeout: 3min · Wall-clock: 12m35s
This adds a new homepage for the docs as well as fixes a reoccurring issue with multiple playground elements on the same page.
This also brings along a single docs fix to property binding for a corner case where expression values need to pass back literal values for handlers instead of the signal.
Risk
3/10 - Renderer change is small but is a hot loop, cant imagine the fail scenario since literal is used only for handlers.