Findings

For AI agents: this page is Markdown at https://squiggle.sh/docs/performance/findings.md. Every docs page is listed at https://squiggle.sh/llms.txt, and all of them are one file at https://squiggle.sh/llms-full.txt.

Detectors read each session and report what they find: what went wrong in plain words, the source line it points at, and the recorded data it came from. Pick one to see a finding as Squiggle reports it.

warnrender-storm

PriceTicker rendered 48× in one interaction

Where
src/screens/Markets.tsx:41
Evidence
48 commits after one tap on Markets, each linked to its render row

propose_fix → your coding agent

PriceTicker reads the whole prices store, so every tick renders it. Select only the price it shows, then re-run the flow to confirm the finding is gone.

What a finding tells you

  • A title that says what happened, with the numbers: “PriceTicker rendered 48× in one interaction”.
  • Where: the file and line of the component, or the request or query it is about.
  • Evidence: the renders, requests or metrics it was worked out from, so you can check it rather than take its word.
  • A severity, warn or error.

Running the detectors again updates a finding instead of adding a copy.

The detectors

Fifteen detectors look at performance. The limits below are the defaults.

DetectorReports
render-stormA component rendering more than 15 times in one interaction, or 60 times in one second.
memo-missFive or more re-renders where every changed prop was a new object, array or function with the same contents. Fix with useMemo or useCallback.
context-blastTwenty or more components re-rendering from one context change within 200 ms.
long-taskA JS task over 100 ms, with what the CPU was doing at the time. When the stall was profiled, the title names the function: JS thread blocked 484ms in useCartTotals (profiled).
jank-attributionDropped frames or a frame-rate dip, with the work around it ranked as suspects.
js-driven-motionAn animation driven from JS: one component committing 20 or more times a second for at least a second while the main thread runs at twice its idle rate. It freezes whenever JS is busy, so move it to the native driver or the UI thread.
duplicate-requestThe same request twice within three seconds.
waterfall-requestThree or more requests in a row, each waiting for the last, over 500 ms in total.
oversized-responseA response over 2 MB.
slow-ttfbA request waiting over a second for its first byte.
slow-queryA SQLite statement over 20 ms at the 95th percentile (100 ms for a transaction), or one run over five times that.
heap-growthMemory that grows on every visit to the same screen, over three or more visits.
startup-regressionA startup phase more than 25% and 50 ms slower than in the baseline.
nav-loopThe same two screens or requests repeating four or more times, more than your other sessions ever do. Needs 20 stored sessions.
heavy-render-windowHalf a second with more rendering than your app absorbs: the level is learned from your other sessions, where at least 80% of windows above it dropped frames. Needs 20 sessions with frame samples.

Two levels come from your budgets when .squiggle/config.jsonc declares a "*" entry. waterfall-request then reports a chain longer than its waterfallDepth, and jank-attribution a moment that dropped more frames than its droppedFramesPerInteraction. With the defaults squiggle init writes, that is a chain of three requests and three dropped frames. See Set a budget per screen.

Rage taps, dead zones and confusion are found the same way; see Friction and the journey.

In Studio

Findings are on the Performance screen’s Insights section. While your app is connected, Studio runs the detectors every few seconds, counts the findings on its card, and sends one notification for each new problem.

Loading the live Studio…
Findings, each with its evidence. Live, in your browser.Open in Studio

Click a finding’s evidence to highlight the request in the network list, select the component in the Inspector, or open its line in your editor.

Timeline, resources & insightsStudio tour · 9 steps

In the terminal

Terminal
squiggle perf insightsinsights 4 · session mv6rxxns-1  ▌ long-task JS thread blocked 484ms — js_long_task  ▌ jank-attribution UI fps 38.7 — top suspect: NavigationContent

squiggle perf watch follows the store and prints each new finding once, as the detectors produce it.

Have your agent fix one

The propose_fix tool turns a finding into a plan for your agent: the component’s code, what the detector measured, and a fix worded only as firmly as the evidence allows. It never edits a file. Your agent makes the change as a normal edit you can review, then runs the flow again to check the finding is gone.

It refuses a finding that names no component (a long task or a duplicate request), a component inside node_modules, and a file it can’t find on your Mac.

See which detectors matter for your app

squiggle perf detector-stats compares flow runs that failed an assertion with runs that passed, and shows how often each detector fired on each:

Terminal
squiggle perf detector-statsdetector           fires on failed  fires on clean  liftlong-task          33 (37.5%)       335 (11.2%)      3.34×jank-attribution   31 (35.2%)       496 (16.6%)      2.12×render-storm       11 (12.5%)       385 (12.9%)      0.97×