macOS: webview freezes after sleep (WebContent↔Networking IPC dies); no way to recycle the web process
Symptom
After some sleep/wake cycles on macOS, a window's webview freezes for good: input is dead, no fetch the page issues ever resolves, nothing repaints. The native window, menus and the app's own server keep working. Focus, hide/unhide, minimize/restore and dock reopen do not recover it. Only a relaunch does.
What is actually broken
Instrumented on a frozen instance:
- Page JS keeps running: our reconnect loop kept scheduling fetches
(visible as
scheduleLoadin the unified log), but none ever reached the server. - The app's
com.apple.WebKit.Networkingprocess still received bytes on the already-open socket to our server (nettop), so the socket and the server were fine. The bytes never reached the page. ProcessThrottlertransitions looked healthy, so this is not App Nap.kill -9of the app'scom.apple.WebKit.WebContentprocess: WebKit respawned it in about a second, every page reloaded, full recovery, no app restart.
So the WebContent↔Networking IPC session is dead, and the only recovery is discarding the WebContent process and letting WebKit recreate it. A wake signal alone cannot fix it.
What electrobun offers today (checked on main, 19ce707)
- No sleep/wake event:
package/src/sdks/main/events/ApplicationEvents.tshasapplication-menu-clicked,context-menu-clicked,open-url,reopen,before-quit; nothing power-shaped. NoNSWorkspacewake observer inpackage/src/native/macos/nativeWrapper.mm. webViewWebContentProcessDidTerminate:is not implemented onMyNavigationDelegate, so an app never learns that its web process died.- No API to terminate or recycle a webview's web process.
BrowserView.tshas none; the native SDKs'reloadWebviewis a plain[WKWebView reload], which runs through the same dead process and does not recover it.
Proposal
Electrobun.events.on("did-wake", ...): anNSWorkspaceDidWakeNotificationobserver innativeWrapper.mm, forwarded the wayreopenalready is viag_appReopenHandler.webview.terminateWebProcess(), plus a realwebViewWebContentProcessDidTerminate:that emits a webview event (optionally auto-reloading). Together they let an app recover in place without hunting WebKit-owned pids from outside electrobun.
Workaround we ship
The page heartbeats POST /alive every 5s. If windows are open and no
window has beaten for 20s after a wake, the main process finds the
com.apple.WebKit.Networking peer on our server port (lsof), resolves its
responsible pid via the unprivileged responsibility_get_pid_responsible_for_pid
(launchctl procinfo is root-gated on macOS 26.5), and kill -9s every
com.apple.WebKit.WebContent sharing it. WebKit respawns and reloads. It
works, but no app should have to do this.
Versions
Observed on electrobun 1.16.0, macOS 26.5.1, Apple Silicon. Gaps above
verified against main at 19ce707 (v2.0.2-beta.17).
Written by Claude Fable on behalf of @shime while building https://dialog.software.
Source: blackboardsh/electrobun