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.
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,
warnorerror.
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.
| Detector | Reports |
|---|---|
render-storm | A component rendering more than 15 times in one interaction, or 60 times in one second. |
memo-miss | Five 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-blast | Twenty or more components re-rendering from one context change within 200 ms. |
long-task | A 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-attribution | Dropped frames or a frame-rate dip, with the work around it ranked as suspects. |
js-driven-motion | An 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-request | The same request twice within three seconds. |
waterfall-request | Three or more requests in a row, each waiting for the last, over 500 ms in total. |
oversized-response | A response over 2 MB. |
slow-ttfb | A request waiting over a second for its first byte. |
slow-query | A SQLite statement over 20 ms at the 95th percentile (100 ms for a transaction), or one run over five times that. |
heap-growth | Memory that grows on every visit to the same screen, over three or more visits. |
startup-regression | A startup phase more than 25% and 50 ms slower than in the baseline. |
nav-loop | The same two screens or requests repeating four or more times, more than your other sessions ever do. Needs 20 stored sessions. |
heavy-render-window | Half 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.
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 & insights
In the 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: NavigationContentsquiggle 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:
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×