# Component Render Profiler

## Objective

Show which components re-render, what triggered it, and which of those actually cost anything.

A development-only instrument that records render counts, their causes, and their durations for the app's live screens.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Instrument the app's real screens rather than a test harness. Re-render problems come from the shape of actual data and actual state, and they do not reproduce on three sample rows.
2. Record for each render what changed to cause it, distinguishing a changed input, a state update in the component itself, and a shared value that changed above it.
3. Report duration alongside count, and sort by total time spent. A component that renders two hundred times cheaply matters less than one that renders four times and blocks the main thread each time.
4. Make the instrument switchable at runtime behind an internal control, and make it inert in production builds — measurement is itself a cost, and it must not be one that customers pay.
5. Do not conclude that a frequently rendering component should be memoised. Comparison has its own cost, and the usual real cause is a value being newly constructed on every render above it, which memoising the child does nothing to fix.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Profiling must be off and ideally absent in production builds, since the instrumentation itself changes the timings it reports and adds weight for every user.
- Render count alone is misleading; the report must separate the renders that consume real time from the ones that are effectively free, or the first thing anyone optimises is the wrong thing.
- The cause of each render must be traceable to a specific changed input, local state update, or shared value — a report saying only that something re-rendered gives nobody anywhere to start.
- The tool must not push memoisation as a default remedy, because it frequently adds comparison cost while leaving the newly constructed value that actually caused the problem untouched.
- Long lists will dominate any report simply by being long. Aggregate repeated instances of the same component so one row does not hide everything else.
- The profiler's own output must not be rendered inside the tree it is measuring, or it will show up in its own numbers.
- Timings vary between runs and between machines, so the report should show a distribution or several samples rather than a single figure presented as fact.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Render counts, causes, and durations are recorded for the app's real screens.
- [ ] Each render is attributed to a changed input, local state, or a shared value from above.
- [ ] The report ranks by total time spent, not by render count.
- [ ] Profiling is toggleable at runtime and inert in production builds.
- [ ] Repeated instances of the same component are aggregated rather than listed individually.
- [ ] The profiler's own interface is excluded from its measurements.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
