Summary
CodexBar can spend noticeably high CPU during OpenAI web dashboard refreshes. A sample taken during a refresh showed the hot path repeatedly moving the full dashboard DOM from WebKit into Swift as document.documentElement.outerHTML, then reparsing embedded JSON from that HTML for auth and account metadata.
Observed behavior
- A normal OpenAI dashboard scrape returns the full
outerHTML payload on every poll.
- Swift then parses
client-bootstrap / page JSON from that HTML to recover fields like auth status, signed-in email, and account plan.
- During a refresh, CPU can spike well above what is expected for a simple menu bar app.
Expected behavior
Normal dashboard scrapes should return only the structured fields CodexBar needs. Full HTML should be collected only for explicit debug dumps or fallback diagnostics.
Suspected cause
OpenAIDashboardScrapeScript returns bodyHTML for every scrape, and OpenAIDashboardFetcher uses that payload to parse auth/account metadata. This is expensive because it:
- serializes a large live DOM in WebKit,
- crosses the WebKit/Swift bridge with a large string,
- reparses embedded JSON in Swift even though JavaScript can extract the same fields before returning.
Proposed fix
Move auth/email/plan extraction into the existing scrape script and stop returning bodyHTML during normal scrapes. Keep full HTML retrieval only behind debugDumpHTML for login, Cloudflare, and no-data diagnostic paths.
Validation
Patch branch:
perf/openai-web-scrape-payload
Passing checks:
swift test --filter OpenAIDashboardScrapeScriptTests
swift test --filter OpenAIDashboardFetcherCreditsWaitTests
swift test --filter OpenAIDashboardParserTests
make check
- local release package with
CODEXBAR_SIGNING=adhoc CODEXBAR_WIDGET_METADATA_MODE=skip ./Scripts/package_app.sh release
Full suite note:
swift test currently reports 2 unrelated failures:
MistralUsageParserTests.swift:115 date month expectation
ProviderStorageFootprintTests.swift:401 storage generation expectation
Impact
This should reduce CPU and memory churn during OpenAI web refreshes without changing the user-visible menu data, because the scrape still returns the same dashboard rows, usage breakdown, body text, login state, email, and plan metadata needed by the fetcher.
Summary
CodexBar can spend noticeably high CPU during OpenAI web dashboard refreshes. A sample taken during a refresh showed the hot path repeatedly moving the full dashboard DOM from WebKit into Swift as
document.documentElement.outerHTML, then reparsing embedded JSON from that HTML for auth and account metadata.Observed behavior
outerHTMLpayload on every poll.client-bootstrap/ page JSON from that HTML to recover fields like auth status, signed-in email, and account plan.Expected behavior
Normal dashboard scrapes should return only the structured fields CodexBar needs. Full HTML should be collected only for explicit debug dumps or fallback diagnostics.
Suspected cause
OpenAIDashboardScrapeScriptreturnsbodyHTMLfor every scrape, andOpenAIDashboardFetcheruses that payload to parse auth/account metadata. This is expensive because it:Proposed fix
Move auth/email/plan extraction into the existing scrape script and stop returning
bodyHTMLduring normal scrapes. Keep full HTML retrieval only behinddebugDumpHTMLfor login, Cloudflare, and no-data diagnostic paths.Validation
Patch branch:
perf/openai-web-scrape-payloadPassing checks:
swift test --filter OpenAIDashboardScrapeScriptTestsswift test --filter OpenAIDashboardFetcherCreditsWaitTestsswift test --filter OpenAIDashboardParserTestsmake checkCODEXBAR_SIGNING=adhoc CODEXBAR_WIDGET_METADATA_MODE=skip ./Scripts/package_app.sh releaseFull suite note:
swift testcurrently reports 2 unrelated failures:MistralUsageParserTests.swift:115date month expectationProviderStorageFootprintTests.swift:401storage generation expectationImpact
This should reduce CPU and memory churn during OpenAI web refreshes without changing the user-visible menu data, because the scrape still returns the same dashboard rows, usage breakdown, body text, login state, email, and plan metadata needed by the fetcher.