Field note 02

Mobile / Motion & performance 3 min read

Every frame
has a deadline.

A practical guide to React Native at 120Hz: find the missed deadline, isolate the work and measure the change.

The deadline is a budget.

At 60Hz, display updates are roughly 16.7 milliseconds apart. At 120Hz, that interval is about 8.3 milliseconds.

Figure 01 / The frame budget Same work. Less time. Switch the display interval and change the work. One hypothetical workload, two refresh rates, the same 100 ms of time.
Budget
8.3ms
Work per frame
10.0ms
Deadline
1.7 ms past the deadline
New frames
6of 12 refreshes

A timing model, not a benchmark. The budgets are 1000 ÷ 60 and 1000 ÷ 120 ms; layout (1.5 ms) and render (2.5 ms) are fixed example values. Real rendering involves overlapping stages; this example isolates the work on one critical path.

The instrument above asks a deliberately small question: would the same piece of work finish within either interval? It does not measure this browser or predict an application’s frame rate.

Do not equate the number on a device’s specification sheet with the rate available in every moment. Apple’s CADisplayLink documentation distinguishes the actual display interval from the maximum. Power, thermal conditions and system settings can affect it. Record the conditions alongside a trace so a comparison means something.

Find the work on the critical path.

Start with the interaction that feels wrong: opening a screen, dragging a control or scrolling a long list. In React Native, a busy JavaScript thread can delay JavaScript-driven updates even while a native scroll view keeps moving. The performance guide explains why those observations can coexist. A smooth scroll alone does not prove that taps are responsive.

For supported properties, Animated’s native driver sends an animation to native code before it starts, avoiding JavaScript work on each frame. It does not remove the cost of preparing a destination screen. Trace the transition and the first interaction after it; an attractive animation can still arrive at an unresponsive view.

Lists make the trade-off visible.

A longer render window can reduce blank areas, but retains more content. Larger batches can fill a list faster while keeping JavaScript busy longer. These are competing constraints, not settings to turn up together. React Native’s FlatList configuration guide describes the trade-offs. Use known item dimensions when they are genuinely predictable; do not force a fixed height onto text that must grow.

Build a test list with the awkward cases: long titles, missing images, mixed row lengths and a slow response. Scroll quickly, reverse direction and select an item before everything settles. Then repeat with larger accessibility text. The useful result is a configuration that survives those interactions, not an empty list that scrolls beautifully.

Change one thing. Compare again.

Profile a release build on a real device; development overhead can distort the picture. Keep the build, device, data set and gesture sequence in your test record. Separate launch readiness, frame timing and response to input. They describe different parts of the experience and should not disappear into one “fast” score.

  1. Capture the baseline. Save a trace of the actual slow interaction and write down what a person would notice.
  2. Test a specific hypothesis. Reduce one source of work, then repeat the same sequence. Check adjacent behavior for regressions.
  3. Keep the comparison. Record both runs and the conditions. Include a slower device and a reduced-motion path before release.

A frame budget helps locate a problem. The acceptance test is still the task: can someone move through the screen, change their mind and finish without waiting for the interface to catch up?

About this note

Sources are linked beside the relevant discussion. The diagrams explain concepts; they do not report a client project or a product benchmark.

Technical review / 22 September 2026