Performance
Performance is an acceptance criterion here, not a sentence. This section states what is measured, how, and what is never claimed. Every number on these pages is read from a file written by a script in this repository; a missing file renders as not measured.
On this page
What is measured
- The production output of every entry point: raw, gzip and brotli bytes per behavior registration, per table module and per stylesheet, with the budget each size script enforces (Budgets).
- What a consumer application ships: five small Vite applications built in production mode with
every
@svelte-lean/*module isolated into one chunk, asserted module by module. - Listener count against instance count: one and a thousand tabs roots, counted by the runtime
and, independently, by a wrapper around
addEventListenerinstalled before any page script. - Startup and interaction timings of a thousand tabs roots and of a table with a thousand and ten thousand rows, as separate entries, never one score.
- Heap, DOM nodes and listeners after repeated mount and unmount cycles.
The model sentence of this section, with its number read from the fixture file: the native-only
fixture, a page with button, dialog and popover markup and the package styles, ships 0 B of Svelte Lean behavior
JavaScript in its production build(Vite 7.3.6, Svelte 5.57.1). The same file records
that no svelte-lean chunk was emitted for it at all.
What is not claimed
- No comparison with another library. A comparison would have to implement the same behavior with equivalent markup and styling, build both sides for production, publish its source, disclose versions, browser and hardware, repeat runs and hide no losing scenario. None exists; when one is built, it lives in the playground and its results are published whichever way they go.
- No superlative. Performance varies with the component, the application, the browser, the hardware and the interaction; the design goal is to remove runtime work where the platform already provides the behavior, and the measurements show what that removes.
- No cross-browser numbers. Every measurement runs in Chromium (Google Chrome locally, Playwright's Chromium in CI); Firefox and WebKit runs do not exist yet.
- No promise from a timing. A published timing is a statement about the recorded environment; another machine produces another number.
The claim registry lists every public claim with its evidence and status: docs/proof/claims.md.
Shipping invariants
Five release-blocking invariants from ADR 0005. The status column reads the fixture results file where the invariant is asserted by a fixture.
| Invariant | Where it is tested | Status |
|---|---|---|
| A. Native-only pages ship no behavior runtime | fixtures/native-only; packages/primitives/scripts/size.mjs (native-only build) | passing |
| B. Unused behaviors are absent from production output | fixtures/tabs-only, tabs-and-menu, manual-registration, table-basic | passing |
| C. Instance count does not multiply shared listeners | apps/playground/tests/primitives/listeners.spec.ts (1 versus 1000 roots); packages/primitives/tests/tabs.test.ts | exact assertion in the browser suite |
| D. Tier 2 state is lazy | packages/primitives/tests/combobox.test.ts ("lazy controller": no state for untouched roots, 1000 roots, session count); apps/playground/tests/primitives/lazy.spec.ts (100 roots: 0 controllers after load, 1 per interacted root, released on close and focus loss) | exact assertion in the browser suite |
| E. Compatibility code is opt-in | No test yet: no compatibility module exists. The first one adds a fixture that proves the native path excludes it. | not applicable yet |
Fixture status from fixtures/results.json, written by yarn test:fixtures (Node v22.23.3, Vite 7.3.6, Svelte 5.57.1).
Proof hierarchy
Four levels of evidence, each answering a question the one before cannot. Intent alone is not enough; a bundle proves what shipped; a browser proves what ran; a composed page proves that the architecture survives real use.
| Level | What it proves | Where |
|---|---|---|
| Level 1 · Architecture | The code: each contract declares its tier, events and native base, and the registry tests assert that the root entry registers nothing. | packages/primitives/src/<name>/contract.md and contract.ts |
| Level 2 · Build | Production output: the consumer fixtures assert which modules are in the graph and which strings are absent from the emitted code; the size scripts record every entry point. | fixtures/results.json, packages/*/artifacts/size.json |
| Level 3 · Runtime | A real browser: listener counts at one and a thousand roots, keyboard and focus contracts, native paths with JavaScript disabled, timings. | apps/playground/tests, and live on the proof page of this site |
| Level 4 · Application | A composed page: this site is built with the ecosystem it documents, with the plugin, the styles and the behaviors in use on every page, and the Settings application on /demos/settings composes the primitives and the table with a runtime panel and a without-JavaScript checklist. | apps/docs, /demos/settings |
Read next
- Methodology: how every number is produced, the environment it is recorded in, and the command that reproduces it.
- Budgets: the value each size script fails on, next to the measured value, with the architecture targets marked as targets.
- Results: the measured numbers, sizes, fixtures, listeners, timings and memory, each with its environment and command, and the thousand-row table.
- Proof: the live runtime inspector of this site, with one, a hundred or a thousand tabs roots mounted on demand.