Performance pass !50

merged merged by cmc on 2026-10-19 06:36 UTC · krz/moonrise:perf into main

Discussion

cmc

Fixes from the performance pass. Measured on the iPhone 17 Pro simulator (release build) and the Mac.

  1. Library images are decoded at display size (ImageIO thumbnails: 260 pt cards, 640 pt featured, 900 pt page header) and kept in a 60 MB NSCache. Memory after opening the Library: 209 MB → 56 MB. Same loader for Mars and news thumbnails.
  2. URLCache.shared set to 24 MB memory / 400 MB disk at launch (default 512 KB / ~20 MB; responses over 5% of disk were never stored, which excluded most Library photos).
  3. 3D view: surface maps load asynchronously and are swapped in as they arrive, instead of ~0.6 s of synchronous loading on the main thread when the view opens.
  4. Library search uses a folded-text index built once and no longer does an O(n²) membership check: 62 → 10 ms per keystroke (Mac, release).
  5. LibraryPage.related() is cached per page: 18 ms → under 1 µs on repeat.
  6. Catalog.starsByHR is built once; constellation thumbnails and the Library's tonight picks used to rebuild a 9,000-star dictionary each time.
  7. Satellite passes (~0.7 s on a Mac for 158 objects) are reused for an hour unless the place or orbits change.
  8. Feeds are kept in memory between tab switches: Sun 5 min, launches 5 min, news 10 min, Mars images 30 min. Pull to refresh still forces a fetch.
  9. Backend GET responses send Cache-Control: today 60 s, launches 300 s, satellites 3600 s, live 300 s. Deployed.

Not changed: launch time. On the simulator under Instruments it is dominated by system and SwiftUI start-up, not app code; it needs measuring on a device.