User Guide

Practical setup, review, benchmarking, testing, and troubleshooting for the performance lab.

Use this guide to run the lab, review the slow and optimized implementations, and find the right supporting documentation. Detailed metric definitions, profiling notes, trace instructions, and result tables remain in their dedicated pages.

Project Overview

Frontend Performance Lab compares two React dashboards with the same dataset, controls, visual design, and benchmark scenarios:

The comparison is designed for repeatable engineering review. The slow app is intentionally inefficient, but it should remain usable and behaviorally equivalent to the optimized app.

Repository Architecture

PathResponsibility
slow-app/Intentionally inefficient React and Vite implementation
optimized-app/Equivalent UI with targeted performance optimizations
benchmark/src/Shared deterministic data, profiling helpers, hooks, UI, and design tokens
benchmark/README.mdCanonical benchmark scenarios and measurement rules
docs/User guide and focused measurement documentation
e2e/Playwright tests against the production Pages-like artifact
scripts/Static-site assembly, serving, and verification orchestration
site/Generated GitHub Pages artifact; never edit it manually

Review Path

  1. Open the project home for the published artifact map.
  2. Review the slow app and run its benchmark controls.
  3. Repeat the same interactions in the optimized app.
  4. Use the Benchmark Protocol to keep inputs and scenario order consistent.
  5. Read Metrics and Profiling Notes when interpreting the panels.
  6. Record only real measurements in Results Before and After.

Running Locally

Use Node.js >=24.15.0 <25 and npm.

Install dependencies:

npm ci

Start either implementation in Vite development mode:

npm run dev:slow
npm run dev:optimized

Run one development command at a time and use the URL printed by Vite.

For the complete production-like artifact and validation flow:

npx playwright install chromium
npm run verify
npm run pages:serve

Open the URL printed by the static server. The local site uses the same /frontend-performance-lab/ base path as GitHub Pages.

Benchmark Workflow

The Benchmark Protocol is the source of truth for scenarios, fixed inputs, and measurement rules.

For a review session:

  1. Use production output from npm run verify or the deployed Pages site.
  2. Keep browser version, viewport, dataset size, and interaction order identical for both apps.
  3. Run each scenario once as a warm-up, restore the same starting state, then repeat it for the recorded observation.
  4. Compare React Profiler commits, interaction duration, rows in the DOM, and production bundle output.
  5. Use Browser Trace Export when panel metrics need main-thread evidence.
  6. Store observations in the Results template without estimating missing values.

Slow vs Optimized

AreaSlow implementationOptimized implementation
Data derivationRecomputed during renderMemoized around stable inputs
SearchApplies every input changeApplies a short debounce
Account tableRenders the full result setRenders a virtual window
ChartIncluded in the initial bundleLoaded through a lazy boundary
ImagesEager loading and synchronous decodingLazy loading and asynchronous decoding
State and callbacksBroad state ownership and unstable callbacksLocal state and stable callbacks on expensive paths

These differences are intentional. Visual design, data, controls, and benchmark scenarios should remain comparable.

Interpreting Metrics

Treat the dashboard values as evidence from the current browser session, not universal performance scores. Compare slow and optimized runs only under matched conditions.

Use Metrics for definitions and expected signals. Use Profiling Notes for implementation context and DevTools checks. Source-level marks and JSDOM tests do not replace a real browser trace.

Browser Traces

Capture a trace only when you need to explain scripting, rendering, layout, paint, or main-thread blocking for one focused scenario. Follow Browser Trace Export for the manual Chrome or Edge DevTools workflow.

Trace files are local measurement artifacts and are not generated by CI.

Testing Strategy

CommandPurpose
npm run typecheckValidate strict TypeScript contracts
npm run lintCheck source and test quality rules
npm run testRun Vitest unit and component tests
npm run coverageGenerate V8 coverage under site/coverage/
npm run e2eRun Chromium E2E tests against the assembled site
npm run verifyExecute the complete local quality gate

Playwright uses a deterministic row-count override to bound E2E runtime. Published app routes still default to 20,000 rows.

Documentation Map

ResourceUse it for
Documentation indexBrowse all published guides and reports
Benchmark ProtocolScenarios, fixed inputs, and measurement rules
MetricsRuntime and manual result field definitions
Profiling NotesInstrumentation and implementation context
Browser Trace ExportManual trace capture and review
Results Before and AfterReal measurement recording template
TypeDocReusable TypeScript API reference
CoverageGenerated unit and component coverage report

Troubleshooting

npm reports an unsupported engine

Check node --version. The repository requires Node.js >=24.15.0 <25.

npm ci reports that the lockfile is out of sync

Use the committed package-lock.json. When dependencies intentionally change, regenerate and commit the lockfile with the repository's npm version before running npm ci again.

Playwright cannot find Chromium

Run:

npx playwright install chromium

Coverage or TypeDoc is missing from the local site

Run npm run verify before npm run pages:serve. The verification command generates coverage, app builds, TypeDoc, documentation pages, and the final Pages-like artifact.

A direct local route returns 404

Use npm run pages:serve and open the /frontend-performance-lab/ URL printed by the server. Opening generated HTML directly does not reproduce the deployed base path.