|
1 | 1 | --- |
2 | | -description: Benchmarking guidelines using examples/benchmark (suite selection, commands, and what packages are exercised) |
3 | | -globs: examples/benchmark/**, .github/workflows/benchmark.yml, packages/normalizr/src/**, packages/core/src/**, packages/endpoint/src/schemas/** |
| 2 | +description: Benchmarking guidelines using examples/benchmark and examples/benchmark-react (suite selection, commands, and what packages are exercised) |
| 3 | +globs: examples/benchmark/**, examples/benchmark-react/**, .github/workflows/benchmark.yml, .github/workflows/benchmark-react.yml, packages/normalizr/src/**, packages/core/src/**, packages/endpoint/src/schemas/**, packages/react/src/** |
4 | 4 | alwaysApply: false |
5 | 5 | --- |
6 | 6 |
|
7 | | -# Benchmarking (`@examples/benchmark`) |
| 7 | +# Benchmarking |
8 | 8 |
|
9 | | -When working on performance investigations or changes that might impact performance, use **`@examples/benchmark`** as the canonical benchmark harness. |
| 9 | +## Node benchmark (`@examples/benchmark`) |
| 10 | + |
| 11 | +When working on performance investigations or changes that might impact **core, normalizr, or endpoint** (no browser, no React), use **`@examples/benchmark`** as the canonical harness. |
| 12 | + |
| 13 | +## React benchmark (`@examples/benchmark-react`) |
| 14 | + |
| 15 | +When working on **`packages/react`** or comparing data-client to other React data libraries (TanStack Query, SWR, baseline), use **`@examples/benchmark-react`**. |
| 16 | + |
| 17 | +- **Where it lives**: `examples/benchmark-react/` |
| 18 | +- **How to run**: From repo root: `yarn build:benchmark-react`, then `yarn workspace example-benchmark-react preview &` and in another terminal `cd examples/benchmark-react && yarn bench` |
| 19 | +- **What it measures**: Browser-based init/update duration, ref-stability counts, sorted-view (Query memoization), optional memory (heap delta), startup metrics (FCP/TBT), and React Profiler commit times. Compares data-client, TanStack Query, SWR, and a plain React baseline. |
| 20 | +- **CI**: `.github/workflows/benchmark-react.yml` runs on changes to `packages/react/src/**`, `packages/core/src/**`, `packages/endpoint/src/schemas/**`, `packages/normalizr/src/**`, or `examples/benchmark-react/**` and reports via `rhysd/github-action-benchmark` (customSmallerIsBetter). CI runs **data-client only** (hot-path scenarios) to track regressions; competitor libraries (TanStack Query, SWR, baseline) are for local comparison only. |
| 21 | +- **Report viewer**: Open `examples/benchmark-react/bench/report-viewer.html` in a browser and paste `react-bench-output.json` to view a comparison table and charts. Toggle "React commit" and "Trace" filters. Use "Load history" for time-series. |
| 22 | + |
| 23 | +See `@examples/benchmark-react/README.md` for methodology, adding a new library, and interpreting results. |
| 24 | + |
| 25 | +### Scenarios and what they exercise |
| 26 | + |
| 27 | +Use this mapping when deciding which React benchmark scenarios are relevant to a change: |
| 28 | + |
| 29 | +- **Get list scenarios** (`getlist-100`, `getlist-500`) |
| 30 | + - Exercises: full fetch + normalization + render pipeline (ListView auto-fetches from list endpoint) |
| 31 | + - Relevant for: `@data-client/react` hooks, `@data-client/core` store initialization |
| 32 | + - All libraries |
| 33 | + |
| 34 | +- **Update propagation** (`update-single-entity`, `update-shared-user-500-mounted`, `update-shared-user-10000-mounted`) |
| 35 | + - Exercises: store update → React rerender → DOM mutation |
| 36 | + - Relevant for: `@data-client/core` dispatch/reducer, `@data-client/react` subscription/selector |
| 37 | + - All libraries (normalization advantage shows with shared user at scale) |
| 38 | + |
| 39 | +- **Ref-stability** (`ref-stability-issue-changed`, `ref-stability-user-changed`) |
| 40 | + - Exercises: referential equality preservation through normalization |
| 41 | + - Relevant for: `@data-client/normalizr` denormalize memoization, Entity identity |
| 42 | + - All libraries (data-client should show fewest changed refs) |
| 43 | + |
| 44 | +- **Sorted/derived view** (`sorted-view-mount-500`, `sorted-view-update-entity`) |
| 45 | + - Exercises: `Query` schema memoization via `useQuery` (data-client) vs `useMemo` sort (competitors) |
| 46 | + - Relevant for: `@data-client/endpoint` Query, `@data-client/normalizr` MemoCache, `@data-client/react` useQuery |
| 47 | + - All libraries |
| 48 | + |
| 49 | +- **Optimistic update** (`optimistic-update`) — data-client only |
| 50 | + - Exercises: `getOptimisticResponse` + `controller.fetch` pipeline |
| 51 | + - Relevant for: `@data-client/core` optimistic dispatch |
| 52 | + |
| 53 | +- **Invalidation** (`invalidate-and-resolve`) — data-client only |
| 54 | + - Exercises: `controller.invalidate` → Suspense fallback → `controller.setResponse` re-resolve |
| 55 | + - Relevant for: `@data-client/core` invalidation, `@data-client/react` Suspense integration |
| 56 | + |
| 57 | +### Expected variance |
| 58 | + |
| 59 | +| Category | Scenarios | Typical run-to-run spread | |
| 60 | +|---|---|---| |
| 61 | +| **Stable** | `getlist-*`, `update-single-entity`, `ref-stability-*`, `sorted-view-mount-*` | 2–5% | |
| 62 | +| **Moderate** | `update-shared-user-*`, `sorted-view-update-*` | 5–10% | |
| 63 | +| **Volatile** | `memory-mount-unmount-cycle`, `startup-*`, `(react commit)` suffixes | 10–25% | |
| 64 | + |
| 65 | +Regressions >5% on stable scenarios or >15% on volatile scenarios are worth investigating. |
| 66 | + |
| 67 | +### When to use Node vs React benchmark |
| 68 | + |
| 69 | +- **Core/normalizr/endpoint changes only** (no rendering impact): Run `examples/benchmark` (Node). Faster iteration, no browser needed. |
| 70 | +- **React hook or Provider changes**: Run `examples/benchmark-react`. Captures real rendering cost. |
| 71 | +- **Schema changes** (Entity, Query, All): Run both — Node benchmark for raw throughput, React benchmark for rendering impact. |
| 72 | +- **Performance investigation**: Start with Node benchmark to isolate the JS layer, then validate with React benchmark for end-to-end confirmation. |
| 73 | + |
| 74 | +--- |
| 75 | + |
| 76 | +# Node benchmark details (`@examples/benchmark`) |
10 | 77 |
|
11 | 78 | ## Optimization workflow |
12 | 79 |
|
|
0 commit comments