perf(desktop): faster session resume & warm AudioContext at idle

- Resume: fire the REST transcript prefetch and the session.resume RPC in
  parallel, and skip the redundant message conversion + reconciliation
  when the prefetch already hydrated the transcript.
- Haptics: web-haptics builds its AudioContext lazily on first trigger,
  paying the ~850ms CoreAudio spin-up on the first streamStart haptic as
  the first token paints. Open/close a throwaway context at idle so the
  real one connects to an already-warm audio service.
This commit is contained in:
Brooklyn Nicholson
2026-06-12 21:07:40 -05:00
parent edc36f3a45
commit 3cf7d43262
2 changed files with 57 additions and 17 deletions
@@ -15,5 +15,29 @@ export function HapticsProvider({ children }: { children: ReactNode }) {
return () => registerHapticTrigger(null)
}, [muted, trigger])
// web-haptics builds its AudioContext lazily inside the first trigger(), and
// the process's first AudioContext pays the CoreAudio spin-up (~850ms stall
// in profiles) — which landed on the first streamStart haptic as the first
// token painted. Open/close a throwaway context at idle so the real one
// connects to an already-warm audio service in single-digit ms.
useEffect(() => {
if (typeof requestIdleCallback !== 'function' || typeof AudioContext === 'undefined') {
return undefined
}
const id = requestIdleCallback(
() => {
try {
void new AudioContext().close().catch(() => undefined)
} catch {
// No audio device (headless CI) — nothing to warm.
}
},
{ timeout: 2000 }
)
return () => cancelIdleCallback(id)
}, [])
return <>{children}</>
}