React Forum
Blog & Guide Responses
May 23, 2023 · 04:00 PM

[Deep Dive #59] Rendering Budgeting - discussion

Started by Morgan Patel
react-docsdeep diverenderingbudgetstreatiescapMsburstAllowancedegradeModeledgersevidence

Deep Dive #59 treats a rendering budget as a treaty: the route shell owns transitions, the component router owns internal navigation, and the render path must produce evidence. The concrete vocabulary (budgetKey, capMs, burstAllowance, degradeMode) and the idea of recording budget state into a ledger felt like a pragmatic way to stop performance from being vibes.

Read the post

Have you actually published budget treaties per track, or do you enforce a single global bar? Do you measure render cost in dev only, or do you ship lightweight budget evidence in prod too? What degrade modes have worked best in real apps: cache, skeleton, freeze, or something else? How do you keep budget enforcement from becoming a constant battle with feature work?

Comments (22)

Back to latest
Hana Saito
May 27, 2023 · 04:40 AM

Per-track treaties.

Global budgets were always unfair to at least one surface.

Rafael Soto
Jun 03, 2023 · 04:04 AM

We recorded budget transitions as tips lines and it made performance work more concrete:

txt
[tips] budgetKey=explorer.grid capMs=12 burst=2 degrade=skeleton
[tips] render costMs=18 overCap=1 reason=filter:commit
[tips] budget degradeMode=skeleton reason=burstExceeded

Without the story, people just argue about memoization.

Mei Tan
Jun 12, 2023 · 12:12 PM

The phrase that stuck with me: a budget is only real if it's enforced in the shell and recorded in render.

If you can't render the budget state, you can't audit it and you can't migrate it.

Jun Park
Jun 18, 2023 · 06:18 PM

Concrete alternative: don't do budgets, just fix slow stuff when it hurts.

We tried that. It leads to periodic fire drills and regressions. Budgets are annoying, but they prevent the slow creep.

Morgan Patel
Jun 20, 2023 · 08:20 PM

Same. The treaty idea is helpful because it makes performance a product policy, not a dev preference.

Once it's a policy, you can negotiate it explicitly.

Nina Kapoor
Jun 22, 2023 · 10:22 PM

Long-form: degrade modes are where teams panic and do random things.

The post's list (cache/skeleton/freeze) is useful because it forces you to pick a policy up front. We found skeleton works best for list/grid, freeze works best for inspector panels where you don't want selection to drift, cache works best for summary surfaces where freshness is less important.

The key is rendering evidence so users aren't confused about what they're seeing.

Grace McCoy
Jul 07, 2023 · 07:07 AM

Docs tie-in: most performance debates get calmer when you treat rendering posture and evidence as first-class.

Related: Performance and Rendering and Core Concepts.

Caleb Price
Jul 19, 2023 · 07:19 PM

We ship budget evidence in prod as a coarse token (ok/regress) and keep detailed numbers in dev.

It helps support without scaring users with ms numbers.

Lina Ortega
Aug 21, 2023 · 09:21 PM

Short take: budgets force you to decide what responsiveness means for each track.

Ibrahim Saleh
Sep 12, 2023 · 12:12 PM

We ended up treating budget enforcement as a boundary: it takes inputs (budgetKey + treaty), outputs (degradeMode + evidence), and it logs transitions.

Once we treated it like a contract surface, it stopped being a random perf util file.

Evan Brooks
Oct 18, 2023 · 06:18 PM

A small repro that matches the post's philosophy (ledger + treaty):

ts
type Treaty = { capMs: number; burstAllowance: number; degradeMode: 'cache' | 'skeleton' | 'freeze' };
type Ledger = { overCap: number; lastCostMs: number; evidence: string[] };

export function recordCost(ledger: Ledger, treaty: Treaty, costMs: number): Ledger {
  const overCap = costMs > treaty.capMs ? ledger.overCap + 1 : 0;
  const evidence = [`budget:cap:${treaty.capMs}`, `budget:cost:${costMs}`, `budget:over:${overCap}`];
  return { ...ledger, lastCostMs: costMs, overCap, evidence };
}

The point is the ledger is observable, not that this code is perfect.

Arman Qadir
Nov 10, 2023 · 10:10 AM

Long-form counterpoint: cost measurement can be noisy and cause teams to chase ghosts.

We had to adopt a rule: budgets trigger degrade based on trends (multiple over-cap renders) not single spikes. That matches the post's burstAllowance idea.

Anika Sharma
Nov 30, 2023 · 06:06 AM

We made budgets enforceable by tying them to track names. If the track id changes, the budget treaty change is visible and reviewable.

Otherwise people rename tracks and budgets silently break.

Salma Qureshi
Dec 05, 2023 · 05:05 AM

We used skeleton degrade for a while, but we had to ensure skeleton layout matched final layout to avoid CLS.

Rendering budgeting and layout stability are linked.

Dmitri Kline
Dec 12, 2023 · 12:12 PM

Budgets also helped us resist premature memoization.

We stopped arguing about "useMemo everywhere" and started arguing about treaty choices.

Keira Santos
Dec 18, 2023 · 06:18 PM

If you adopt this, invest in evidence keys that survive refactors.

If evidence keys change constantly, budgets won't be auditable.

Priya Liao
Dec 22, 2023 · 10:22 PM

Freeze degrade can be surprisingly good UX if you render an explicit evidence chip explaining it.

Noah Vance
Dec 28, 2023 · 07:19 PM

I like that the post treats budgets as treaties between shell/router/render.

It prevents the failure mode where one team tries to fix perf in a leaf component while the shell keeps doing expensive work on enter.

Rowan Pierce
Dec 29, 2023 · 11:23 PM

Per-track budgets + an auditable ledger is the most realistic performance guidance I've read in a while.

Camille Duarte
Dec 30, 2023 · 09:09 AM

We only got budgets to stick once we made them part of route shell code review, not perf side projects.

Sofia Martinez
Dec 31, 2023 · 04:04 AM

Long-form: budgets also improve product negotiation.

When a feature wants a heavy track, you can say "ok, but then the treaty changes and degrade policy changes". It turns hidden performance cost into an explicit tradeoff.

Tomas Rivera
Dec 31, 2023 · 12:12 PM

If you ship budgets, ship the evidence. Otherwise it's just internal dogma.

Evan Brooks
Dec 31, 2023 · 11:23 PM

Takeaway: render cost isn't a number, it's a contract surface.

Treat it like one and performance becomes something teams can iterate on without superstition.