Find what re-renders
For AI agents: this page is Markdown at https://squiggle.sh/docs/inspector/renders.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.
The Renders tab counts every re-render in your app as it happens: which components re-render most, what set each burst off, which context providers re-render their consumers for nothing, and when something is stuck in a render loop.
You need your app running with the Squiggle SDK and connected to Studio. Render times come from React’s profiler, which only development and profiling builds include: a release build shows how often things re-render, but no times.
Find the components that re-render most
Open the Inspector and choose Renders. The numbers along the top count since you last pressed Reset, and the chart plots renders per second. Drag its crosshair back to read a spike you missed. Under it, Components lists every component that re-rendered, hottest first. A component’s first render doesn’t count, only the ones after it.
| Column | What it shows |
|---|---|
| Component | Its name, and the file and line it is written at. |
| Last 30 s | Its re-renders per second, as a small bar chart. |
| Re-renders | How many times it re-rendered. |
| Per sec | How fast it is re-rendering right now. |
| Last · Total | How long its latest render took, and all of them together. |
| Why | What changed: the props by name, its state or a hook, or a context it reads. |
Click a column heading to sort by it. Hover a row for everything known about the component, and click it to select the component in the tree and outline it on the device.
To count only part of the app, select a component in the tree: the tab then counts what renders under it, and the chip in its header says Under and the component’s name. Clear it to count the whole app again. On device colours the components on the device by the same measure.
Two warnings in the Why column
- memo miss
- Its parent passed new props with the same values. Wrapping the component in
memowould most likely have skipped the render. - new context value
- A context it reads got a new object with the same contents. Fix the provider; see below.
What the colours mean
Green is calm and red is hot, the same in the tree, this list and the device’s Renders overlay. Colour by picks the measure: Re-renders (how many times), Per second (how fast right now) or Either (whichever is hotter).
Find what started a burst
Cascades lists each burst of re-renders that reached more than one component, newest first. Each one names the topmost component that re-rendered, how many components and renders it spread to, and what set it off:
- a gesture, with the control it landed on: Tap on “Add to cart”
- a change to a store a component reads
- a context changing
- new props from above
- the component’s own state or a hook
Click a cascade to select the component it started at. The list keeps the latest 50.
Catch a render loop
A component that keeps re-rendering with nothing happening is usually a loop: something it renders changes what it reads. When one re-renders at least as fast as Loops says (20 a second unless you change it) for three seconds in a row, the tab shows a banner and Studio sends a notification. Select on the banner, or Show on the notification, selects the component.
A loop that takes a whole subtree with it gives one notification, for its topmost component, with the number of components under it. You get another only after it has calmed down and started again. To catch a slower loop, choose 10 a second; to quiet a screen that animates on purpose, choose 30 or 60.
Studio watches for loops while the Inspector is open.
Fix a provider that re-renders its consumers
A context provider that builds its value inline hands down a new object on every render, even when nothing in it changed. Every component that reads the context re-renders with it. Providers lists those providers with the components each one re-rendered for nothing, and those components carry new context value in Components. The fix is to keep the value the same object until its contents change:
// A new object on every render: every component that reads CartContext// re-renders whenever CartProvider does.<CartContext.Provider value={{ items, addItem }}>// The same object until items or addItem changes.const addItem = useCallback((item: Item) => setItems((all) => [...all, item]), []);const value = useMemo(() => ({ items, addItem }), [items, addItem]);<CartContext.Provider value={value}>A provider whose value really changes is not listed: its consumers re-render for a reason.
Hand it to your agent
Copy prompt copies the hottest components, their reasons and where they are written, ready to paste into a coding agent. An agent connected over MCP reads the same counts, cascades, loops and providers itself with the renders tool; see Agent tools.
When something looks wrong
- The list is empty
- Nothing has re-rendered since you pressed Reset, or under the component you selected. Use the app, or clear the selection.
- A row says “call site unknown”
- The component comes from a library, or from code built without source locations, so Squiggle can’t say where it is written. Its parent row usually can.
- Times are missing
- The app is a release build. Counts still work.
- No notification for a component you can see looping
- It is re-rendering slower than Loops, or the Inspector isn’t open. Choose a lower rate.