Skip to content

[v1.0.0] feat(perf): add wp-tooling perf CLI, setup/perf scaffold, and xhprof normalization - #37

Open
Adi-ty wants to merge 3 commits into
release/v1.0.0from
v1.0.0/task/perf-runner
Open

[v1.0.0] feat(perf): add wp-tooling perf CLI, setup/perf scaffold, and xhprof normalization#37
Adi-ty wants to merge 3 commits into
release/v1.0.0from
v1.0.0/task/perf-runner

Conversation

@Adi-ty

@Adi-ty Adi-ty commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

  • Implements wp-tooling perf — a zero-runtime-dep CLI runner that collects Core Web Vitals (web-vitals + Lighthouse) and optional server-side xhprof profiling per URL, with sensible degradation for every failure mode
  • Adds setup/perf scaffold so consumers can bootstrap config, npm scripts, and the PHP xhprof shim in one command
  • Normalises xhprof output (ct/wt/cpu/mu/pmu) into the report's server section alongside frontend metrics, with a fidelity note explaining CLI-context limitations

Closes

Closes https://github.com/rtcamp/wp-devtools/issues/22
Closes https://github.com/rtcamp/wp-devtools/issues/36
Closes https://github.com/rtcamp/wp-devtools/issues/37

Changes

  • Perf runner: per-URL collector that runs web-vitals under headless Chromium, Lighthouse, and optional xhprof server profiling — each layer degrades independently on failure. Config resolution with built-in DEFAULTS and section-level merge, supporting --url override and optional config files. Binary/module resolution walks consumer node_modules with npx --no-install fallback, never fetching from registry. Normalisation pipeline rates metrics against CWV thresholds, extracts Lighthouse scores + failing audits, builds human-readable assessment lines from a single THRESHOLDS registry. CLI layer with dry-run plan printer, text/json emitter, exit codes 0/1/2/3 matching the a11y convention, and a RunnerError hierarchy with machine-readable codes.
  • Setup/perf scaffold: scaffold manifest with six configurable inputs (base URL, page paths, server enable toggle, WP-CLI env-cwd path). Minimal .perfrc.json template emitting only URLs and server settings — all other sections fall through to built-in defaults, preventing silent drift. Server-enabled boolean separated from env-cwd path so profiling the WordPress root (--env-cwd=.) is expressible. Hardened PHP shim that detects xhprof/tideways backends, degrades gracefully to [] when the profiler is absent, unhooks redirect_canonical to prevent early exit(), installs a shutdown-fallback emitter with buffer drain, populates $_GET and REQUEST_URI from the positional path argument, and writes a route diagnostic to stderr.
  • xhprof normalisation: WP-CLI invocation layer that spawns the shim with correct argument order, parses JSON output with preamble tolerance, and captures the stderr diagnostic — every failure degrades to { data: null, error } instead of throwing. URL splitter separating origin from path+query for the shim's two-argument contract. Normaliser maps raw xhprof function data into the report's server section with ct/wt/cpu/mu/pmu fields and a fidelity note explaining CLI-context limitations. Server layer wired into the per-URL collector independently of the browser layer — still profiles even when the frontend scan failed.

How I verified

npm run check

Fixture testing for all exit codes and degradation paths. Scaffold render tests confirm default and custom config output. Also tested end-to-end by running wp-tooling perf against the features skeleton plugin.

Acceptance criteria

Runtime behavior

  • wp-tooling perf --dry-run resolves and prints the plan without executing anything.
  • A JSON report for two URLs validates the shape above; exit codes match a11y (0/1/2/3).
  • The engine core has no TTY-UI dependency (runs headless/CI/AI).
  • wp-tooling add setup/perf yields a runnable test:perf on a consumer, with the dev deps surfaced as developer actions (not auto-installed).
  • wp eval-file server-profile.php --url=... --top=15 --format=json returns top-N JSON when the extension is present, and [] when it is not.
  • No file overwrite, no package-manager execution, no secret values.
  • A perf report from a consumer run carries both the frontend and the server layer per URL.
  • The fidelity note is present in the report.
  • Fixture tests for the normalizer are green (frontend-only, server-only, and combined).

Code quality

  • Lint — zero errors
  • Static analysis — zero errors
  • Tests pass

Housekeeping

  • CHANGELOG.md entry under ## Unreleased
  • .claude/issues/<N>-<slug>.md updated with final state

Full decision log and verification history for this work lives in .claude/issues/wp-devtools-22-36-37-perf-runner.md on this branch.

Adi-ty added 3 commits July 15, 2026 02:50
…ver xhprof)

Mirrors the a11y runner: two-layer normalized report (lab Core Web
Vitals + Lighthouse, plus optional server-side xhprof hotspots over
WP-CLI). Ships src/perf/*, the perf CLI command, package.json exports,
tests, the setup/perf scaffold with a hardened server-profile.php shim,
and CHANGELOG/issue-tracking entries. Includes two pre-existing
lint-gate fixes (no-shadow + prettier in src/init/index.js and
tests/ui/selects.test.js) needed for npm run check to pass, matching
the fix already on the a11y branch.
… retention

- server-profile: catch malformed URL instead of throwing
- run.js: skip Lighthouse when scanError set; extractLighthouse immediately after run; show server.error in text output; guard dry-run against string command
- normalize.js: derive METRIC_NAMES from THRESHOLDS
- collect-vitals.js: import METRIC_NAMES from normalize
- scaffold: split server_enabled from server_env_cwd
- test: de-flake dry-run assertion
@Adi-ty
Adi-ty marked this pull request as ready for review July 15, 2026 04:51
@Adi-ty
Adi-ty requested a review from AnuragVasanwala July 15, 2026 04:51
@Adi-ty Adi-ty self-assigned this Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant