docs: update comparisons

This commit is contained in:
ayo 2026-07-20 22:48:05 +02:00
parent 8f8b09acd3
commit eaadef6716

View file

@ -9,7 +9,7 @@ This page puts these benefits and their cost in context: how much does WCB weigh
## Measured size: the same component in each library ## Measured size: the same component in each library
Numbers below are **measured, not quoted from marketing pages**. The same minimal counter component — one reactive `count` prop, a click handler, a re-render on change — was written idiomatically in each library, bundled with `esbuild --bundle --minify --format=esm`, and compressed with gzip (level 9) and brotli (quality 11). This is the real "cost of your first component": library runtime + component code, everything the browser downloads. Numbers below are **measured** from the same minimal counter component (one reactive `count` prop, a click handler, a re-render on change) written in each library, bundled with `esbuild --bundle --minify --format=esm`, and compressed with gzip (level 9) and brotli (quality 11). This is the real "cost of your first component": library runtime + component code, everything the browser downloads.
| Library | Version | Minified | Gzip | Brotli | | Library | Version | Minified | Gzip | Brotli |
| ------------------------- | ------- | -------- | ------- | ---------- | | ------------------------- | ------- | -------- | ------- | ---------- |
@ -25,21 +25,21 @@ For scale: even after all of the v5.2v6.1 work, the WCB counter is **~21% sma
What each library gives you beyond extending directly from `HTMLElement` — the boilerplate you no longer write by hand: What each library gives you beyond extending directly from `HTMLElement` — the boilerplate you no longer write by hand:
| Capability | WCB 6.1 | Elena 1.0 | Lit 3.3 | FAST 3.0 | | Capability | WCB 6.1 | Lit 3.3 | Elena 1.0 | FAST 3.0 |
| -------------------------------- | ----------------------------------------------------------------------- | --------------------------------------- | -------------------------------------------------------- | ------------------------------------------------ | | -------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------- | --------------------------------------- | ------------------------------------------------ |
| Declarative templates | ✅ `html` tagged templates (htm) or plain strings | ✅ `html` tagged templates | ✅ `lit-html` tagged templates | ✅ typed templates with binding expressions | | Declarative templates | ✅ `html` tagged templates (htm) or plain strings | ✅ `lit-html` tagged templates | ✅ `html` tagged templates | ✅ typed templates with binding expressions |
| Reactive props ⇄ attributes | ✅ `static props`, overrideable converters | ✅ `static props`, opt-in reflection | ✅ `static properties` with converters | ✅ `@attr` / observables | | Reactive props ⇄ attributes | ✅ `static props`, overrideable converters | ✅ `static properties` with converters | ✅ `static props`, opt-in reflection | ✅ `@attr` / observables |
| Update strategy | In-place patch (index-based, non-keyed) | Batched re-renders | Part-based: only touched bindings update, keyed `repeat` | Fine-grained observable bindings, keyed `repeat` | | Update strategy | In-place patch (index-based, non-keyed) | Part-based: only touched bindings update, keyed `repeat` | Batched re-renders | Fine-grained observable bindings, keyed `repeat` |
| Preserves DOM state on re-render | ✅ since v5.2 | ✅ | ✅ | ✅ | | Preserves DOM state on re-render | ✅ since v5.2 | ✅ | ✅ | ✅ |
| Update batching / scheduling | renders per prop write | ✅ batched, `updateComplete` | ✅ async batched, `updateComplete` | ✅ queued/batched | | Update batching / scheduling | ⚠️ renders per prop write | ✅ async batched, `updateComplete` | ✅ batched, `updateComplete` | ✅ queued/batched |
| Keyed list reconciliation | ✅ positional | ❌ | ✅ `repeat` directive | ✅ `repeat` with recycling controls | | Keyed list reconciliation | ⚠️ positional | ✅ `repeat` directive | ❌ | ✅ `repeat` with recycling controls |
| Light DOM by default | ✅ (shadow DOM opt-in via `static shadowRootInit`) | ✅ (shadow opt-in) | ❌ shadow DOM by default | ❌ shadow DOM by default | | Light DOM by default | ✅ (shadow DOM opt-in via `static shadowRootInit`) | ❌ shadow DOM by default | ✅ (shadow opt-in) | ❌ shadow DOM by default |
| Scoped styles | ✅ `static styles` + constructable stylesheets (needs shadow root) | ✅ scoped without shadow DOM | ✅ shadow-scoped CSS | ✅ shadow-scoped + design tokens | | Scoped styles | ✅ `static styles` + constructable stylesheets (needs shadow root) | ✅ shadow-scoped CSS | ✅ scoped without shadow DOM | ✅ shadow-scoped + design tokens |
| SSR / hydration story | ⚠️ attribute-driven state renders from any server; no hydration runtime | ✅ HTML/CSS-first, server utilities | ✅ `@lit-labs/ssr` + hydration | ⚠️ experimental SSR | | SSR / hydration story | ✅ attribute-driven state renders from any server | ✅ `@lit-labs/ssr` + hydration | ✅ HTML/CSS-first, server utilities | ⚠️ experimental SSR |
| Works with zero build tooling | ✅ import from CDN, no compiler | ✅ | ✅ (buildless possible, decorators need tooling) | ⚠️ practical with tooling | | Works with zero build tooling | ✅ import from CDN, no compiler | ✅ (buildless possible, decorators need tooling) | ✅ | ⚠️ practical with tooling |
| Editor/IDE tooling | ✅ typed props + [CEM analyzer plugin](/cem-plugin/) | ✅ CEM-focused | ✅ extensive (analyzer, TS decorators, IDE plugins) | ✅ TS-first | | Editor/IDE tooling | ✅ typed props + [CEM analyzer plugin](/cem-plugin/) | ✅ extensive (analyzer, TS decorators, IDE plugins) | ✅ CEM-focused | ✅ TS-first |
| Lifecycle hooks | `onInit`, `afterViewInit`, `onChanges`, `onDestroy` | `willUpdate`, `firstUpdated`, `updated` | full reactive update lifecycle | full lifecycle + behaviors | | Lifecycle hooks | `onInit`, `afterViewInit`, `onChanges`, `onDestroy` | full reactive update lifecycle | `willUpdate`, `firstUpdated`, `updated` | full lifecycle + behaviors |
| Backing / ecosystem | solo maintainer, small surface | new (2026), design-system focus | Google, huge ecosystem | Microsoft, powers Fluent UI | | Backing / ecosystem | solo maintainer, small surface | Google, huge ecosystem | new (2026), design-system focus | Microsoft, powers Fluent UI |
:::note[Why 11ty WebC isn't here] :::note[Why 11ty WebC isn't here]
WebC is a compile-time tool: it resolves components during an Eleventy build and ships plain HTML with no client runtime. Every row above is about what a library does _in the browser at runtime_, so a side-by-side comparison would be measuring two different things. If your components are static at build time, WebC solves a different problem — and solves it well. WebC is a compile-time tool: it resolves components during an Eleventy build and ships plain HTML with no client runtime. Every row above is about what a library does _in the browser at runtime_, so a side-by-side comparison would be measuring two different things. If your components are static at build time, WebC solves a different problem — and solves it well.