Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ jobs:
- run:
name: Add examples/* to yarn workspace
command: |
npm pkg delete workspaces[6]
npm pkg delete workspaces[5]
npm pkg delete workspaces[4]
npm pkg delete workspaces[3]
Expand Down
6 changes: 3 additions & 3 deletions .cursor/rules/benchmarking.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ When working on performance investigations or changes that might impact **core,

## React benchmark (`@examples/benchmark-react`)

When working on **`packages/react`** or comparing data-client to other React data libraries (TanStack Query, SWR, baseline), use **`@examples/benchmark-react`**.
When working on **`packages/react`** or comparing data-client to other React data libraries (TanStack Query, SWR), use **`@examples/benchmark-react`**.

- **Where it lives**: `examples/benchmark-react/`
- **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`
- **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.
- **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.
- **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, and SWR.
- **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) are for local comparison only.
- **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.

See `@examples/benchmark-react/README.md` for methodology, adding a new library, and interpreting results.
Expand Down
20 changes: 3 additions & 17 deletions .github/workflows/benchmark-react.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ jobs:
node-version: '24'
cache: 'yarn'
- name: Install packages
run: |
corepack enable
yarn install --immutable
run: ./scripts/ci-install.sh examples/benchmark-react
- name: Install Playwright (Chromium + system deps)
run: npx playwright install chromium --with-deps
- name: Build packages
Expand All @@ -57,18 +55,11 @@ jobs:
cd examples/benchmark-react && yarn bench | tee react-bench-output.json

# PR comments on changes
- name: Download previous benchmark data (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: actions/cache@v5
with:
path: ./cache
key: ${{ runner.os }}-benchmark-react-pr-${{ github.run_number }}
restore-keys: |
${{ runner.os }}-benchmark-react
- name: Store benchmark result (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: rhysd/github-action-benchmark@v1
with:
name: 'Benchmark React'
tool: 'customSmallerIsBetter'
output-file-path: examples/benchmark-react/react-bench-output.json
github-token: "${{ secrets.GITHUB_TOKEN }}"
Expand All @@ -82,16 +73,11 @@ jobs:
auto-push: false

# master reports to history
- name: Download previous benchmark data (main)
if: ${{ github.event_name == 'push' }}
uses: actions/cache@v5
with:
path: ./cache
key: ${{ runner.os }}-benchmark-react
- name: Store benchmark result (main)
if: ${{ github.event_name == 'push' }}
uses: rhysd/github-action-benchmark@v1
with:
name: 'Benchmark React'
tool: 'customSmallerIsBetter'
output-file-path: examples/benchmark-react/react-bench-output.json
github-token: "${{ secrets.GITHUB_TOKEN }}"
Expand Down
21 changes: 1 addition & 20 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,13 @@ jobs:
node-version: '24'
cache: 'yarn'
- name: Install packages
run: |
corepack enable
yarn install --immutable
run: ./scripts/ci-install.sh examples/benchmark
- name: Build packages
run: yarn build:benchmark
- name: Run benchmark
run: yarn workspace example-benchmark start | tee output.txt


# PR comments on changes
- name: Download previous benchmark data (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: actions/cache@v5
with:
path: ./cache
key: ${{ runner.os }}-benchmark-pr-${{ github.run_number }}
restore-keys: |
${{ runner.os }}-benchmark
- name: Store benchmark result (PR)
if: ${{ github.event_name == 'pull_request' }}
uses: rhysd/github-action-benchmark@v1
Expand All @@ -67,22 +56,14 @@ jobs:
output-file-path: output.txt
github-token: "${{ secrets.GITHUB_TOKEN }}"
gh-pages-branch: 'gh-pages-bench'
# Show alert with commit comment on detecting possible performance regression
alert-threshold: '150%'
comment-always: true
fail-on-alert: false
alert-comment-cc-users: '@ntucker'
# we only want to compare against master, so do not save for PR
save-data-file: false
auto-push: false

# master reports to history
- name: Download previous benchmark data (main)
if: ${{ github.event_name == 'push' }}
uses: actions/cache@v5
with:
path: ./cache
key: ${{ runner.os }}-benchmark
- name: Store benchmark result (main)
if: ${{ github.event_name == 'push' }}
uses: rhysd/github-action-benchmark@v1
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/beta-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ jobs:
cache: 'yarn'
registry-url: 'https://registry.npmjs.org'
- name: Install packages
run: |
corepack enable
yarn install --immutable
run: ./scripts/ci-install.sh

- name: Create Beta Release Pull Request or Publish to npm
id: changesets
Expand Down
11 changes: 3 additions & 8 deletions .github/workflows/bundle_size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,12 @@ jobs:
node-version: '24'
cache: 'yarn'
- name: Install packages
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: true
run: |
# npm pkg delete workspaces[5]
# npm pkg delete workspaces[4]
# npm pkg delete workspaces[3]
# npm pkg delete workspaces[1]
corepack enable
run: ./scripts/ci-install.sh examples/test-bundlesize
- name: compressed-size-action
uses: preactjs/compressed-size-action@v2
continue-on-error: true
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: false
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
build-script: "ci:build:bundlesize"
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ jobs:
cache: 'yarn'
registry-url: 'https://registry.npmjs.org'
- name: Install packages
run: |
corepack enable
yarn install --immutable
run: ./scripts/ci-install.sh

- name: Create Release Pull Request or Publish to npm
id: changesets
Expand Down
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Monorepo for `@data-client` npm packages.
- **CircleCI** (`.circleci/config.yml`) — PR validation: lint, typecheck, unit tests (React 17/18/native/latest), Node matrix, ESM type checks (TS 4.0–5.3+), browser build.
- **GitHub Actions** (`.github/workflows/`) — release (`changesets`), bundle size PR comments, benchmark regression detection.

Changing root `package.json` `workspaces` requires updating `.circleci/config.yml` (`setup` job) and `.github/workflows/` install steps.

## Changesets

Any user-facing change in `packages/*` requires a changeset. Core packages are version-linked (bumping one bumps all). See skill "changeset" for full workflow.
Expand Down
16 changes: 8 additions & 8 deletions examples/benchmark-react/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# React Rendering Benchmark

Browser-based benchmark comparing `@data-client/react`, TanStack Query, SWR, and a plain React baseline on mount/update scenarios. Built with Webpack via `@anansi/webpack-config`. Results are reported to CI via `rhysd/github-action-benchmark`.
Browser-based benchmark comparing `@data-client/react`, TanStack Query, and SWR on mount/update scenarios. Built with Webpack via `@anansi/webpack-config`. Results are reported to CI via `rhysd/github-action-benchmark`.

## Comparison to Node benchmarks

Expand Down Expand Up @@ -52,13 +52,13 @@ The repo has two benchmark suites:

These are approximate values to help calibrate expectations. Exact numbers vary by machine and CPU throttling.

| Scenario | data-client | tanstack-query | swr | baseline |
|---|---|---|---|---|
| `getlist-100` | ~similar | ~similar | ~similar | ~similar |
| `update-shared-user-500-mounted` | Low (one store write propagates) | Higher (list refetch) | Higher (list refetch) | Higher (list refetch) |
| `ref-stability-issue-changed` (100 mounted) | ~1 changed | ~100 changed (list refetch) | ~100 changed (list refetch) | ~100 changed (list refetch) |
| `ref-stability-user-changed` (100 mounted) | ~5 changed | ~100 changed (list refetch) | ~100 changed (list refetch) | ~100 changed (list refetch) |
| `sorted-view-update-entity` | Fast (Query memoization skips re-sort) | Re-sorts on every issue change | Re-sorts on every issue change | Re-sorts on every issue change |
| Scenario | data-client | tanstack-query | swr |
|---|---|---|---|
| `getlist-100` | ~similar | ~similar | ~similar |
| `update-shared-user-500-mounted` | Low (one store write propagates) | Higher (list refetch) | Higher (list refetch) |
| `ref-stability-issue-changed` (100 mounted) | ~1 changed | ~100 changed (list refetch) | ~100 changed (list refetch) |
| `ref-stability-user-changed` (100 mounted) | ~5 changed | ~100 changed (list refetch) | ~100 changed (list refetch) |
| `sorted-view-update-entity` | Fast (Query memoization skips re-sort) | Re-sorts on every issue change | Re-sorts on every issue change |

## Expected variance

Expand Down
7 changes: 1 addition & 6 deletions examples/benchmark-react/bench/scenarios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,7 @@ const BASE_SCENARIOS: BaseScenario[] = [
},
];

export const LIBRARIES = [
'data-client',
'tanstack-query',
'swr',
'baseline',
] as const;
export const LIBRARIES = ['data-client', 'tanstack-query', 'swr'] as const;

export const SCENARIOS: Scenario[] = LIBRARIES.flatMap(lib =>
BASE_SCENARIOS.filter(
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmark-react/bench/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Usage:
* npx tsx bench/validate.ts # all libraries
* npx tsx bench/validate.ts --lib data-client # one library
* npx tsx bench/validate.ts --lib swr,baseline # multiple
* npx tsx bench/validate.ts --lib swr,tanstack-query # multiple
*/
import { chromium } from 'playwright';
import type { Page } from 'playwright';
Expand Down
6 changes: 3 additions & 3 deletions examples/benchmark-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"swr": "2.3.6"
},
"devDependencies": {
"@anansi/babel-preset": "6.2.23",
"@anansi/babel-preset": "6.2.25",
"@anansi/browserslist-config": "^1.4.3",
"@anansi/webpack-config": "21.1.14",
"@anansi/webpack-config": "21.1.16",
"@babel/core": "^7.22.15",
"@playwright/test": "1.58.2",
"@types/node": "24.11.0",
Expand All @@ -44,7 +44,7 @@
"serve": "14.2.6",
"tsx": "4.19.2",
"typescript": "6.0.1-rc",
"webpack": "5.105.3",
"webpack": "5.105.4",
"webpack-cli": "6.0.1"
},
"browserslist": "extends @anansi/browserslist-config"
Expand Down
Loading
Loading