Skip to content

Faster race loading, smoother menu while cars load - #20

Merged
mbeczynski merged 1 commit into
mainfrom
perf/loading
Oct 21, 2026
Merged

mbeczynski merged 1 commit into
mainfrom
perf/loading

Conversation

@mbeczynski

Copy link
Copy Markdown
Contributor

Change

  • A race waits for 6 cars, not 9: the player's car plus as many as there are rivals (rivals pick their look from the loaded cars). Further cars don't start while the race screen is open: merging a model (up to 0.6 s) and the end of Entity(contentsOf:) (~90 ms) run on the main thread and caused hitches at the start of the race. The rest load after leaving the race screen. On the results screen loading froze the screen for 0.5–0.7 s, so it stays held there too.
  • Load order: two at a time, the player's car first, then the smallest files. In catalogue order the heavy models were holding up the start.
  • MainThreadSlices: mesh merge and applying baked AO run in ~6 ms slices with a 1 ms pause for a frame. In one go they blocked the main thread for 40–510 ms and 54–250 ms per car, and the turntable in the menu stopped.
  • Frame-time log for the menu/garage. The race hitch log also covers the first 0.5 s after the scene is revealed.

Not changed: the ~0.5 s hitch when post-processing starts, under the loading screen. Our pipelines are ready at launch (0.01 s); the time is spent inside RealityKit before it calls our code.

Measurement (iPad M5 iOS 27 simulator, A/B alternating against main)

main this PR
cold start into a race 8.3–8.9 s 7.1–7.8 s
memory during the race 251–278 MB 204–231 MB
longest race frame 17–67 ms 17–50 ms
menu/garage, first 10 s: freezes > 100 ms 11 4–7
longest menu freeze 720–750 ms 440 ms (under the splash, before the menu shows)
total stall time in the menu 5.5–5.7 s 3.9–4.2 s

Tests

  • Debug / Family / Release build
  • XCUITest on a clean install: all 10 (Gameplay 7, GarageColors, AllTracks: every track and every car to the finish), passed; no new crash reports

🤖 Generated with Claude Code

- A race waits for the player's car and five more (rivals pick their look
  from the loaded cars), not all nine. Further cars don't start while the
  race screen is open: merging a model runs on the main thread (up to
  0.6 s) and the end of Entity(contentsOf:) also blocks it.
- Cars load two at a time, player's car first, then smallest files first.
- Mesh merge and baked-AO application run in ~6 ms slices with a pause
  for a frame (MainThreadSlices).
- Frame-time log for the menu/garage turntable; race hitch log also
  covers the first 0.5 s after the scene is revealed.

Simulator iPad M5 iOS 27, A/B against main:
- cold start into a race: 8.3-8.9 s -> 7.1-7.8 s, memory in race -48 MB,
  longest race frame still <= 50 ms
- menu/garage in the first 10 s: freezes over 100 ms 11 -> 4-7, longest
  740 -> 440 ms (now under the splash), total stall time -30%

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbeczynski
mbeczynski merged commit 695114c into main Oct 21, 2026
1 check passed
@mbeczynski
mbeczynski deleted the perf/loading branch October 21, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant