Skip to content

perf: parallel viewports + parallel checks + console dedup#115

Merged
JonasJesus42 merged 3 commits into
mainfrom
perf/inline-checks-and-console-dedup
Jun 17, 2026
Merged

perf: parallel viewports + parallel checks + console dedup#115
JonasJesus42 merged 3 commits into
mainfrom
perf/inline-checks-and-console-dedup

Conversation

@JonasJesus42

@JonasJesus42 JonasJesus42 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Combines what would have been PRs #2 and #3 of the performance plan (their stacked-on-#113 branches got auto-closed when #113 squash-merged). Bundles cleanly because all changes are independent within the file scope.

Parallel viewports + LLM semaphore (was #114):

  • Wraps the viewport loop in runWithConcurrency so mobile,desktop collects fully parallel — 4 BrowserContexts simultaneously (mobile/prod, mobile/cand, desktop/prod, desktop/cand)
  • New --max-viewport-concurrency <n> flag (default 2) for memory-constrained machines or runs with >2 viewports
  • LLM concurrency cap: process-global semaphore in src/llm/client.ts (3 slots) so 4 sides × recovery budget 3 calls never exceed Anthropic tier-1's 4 RPS

Parallel checks + cross-page console dedup (was #115):

  • runAllChecks ran ~27 checks sequentially (~4m26s). Almost all are pure CPU aggregations + 3 are I/O-bound — all parallelize cleanly. Promise.all now collapses the phase to the slowest single check (~30-60s expected).
  • consoleErrorsBaseline was emitting one Issue per (page × error), crowding the report with 4–5 duplicates of the same domain-key mismatch. Now groups by normalized error key across all page pairs and emits ONE issue with the affected-pages list inline (direct response to user feedback). Added a test for the new behavior.

Bumps to 0.11.16. After this PR merges on top of 0.11.14: expected total run wall-clock ~6-8min on bagaggio (down from 25m46s baseline — hitting the plan's goal).

Test plan

  • bun run check clean
  • bun run lint clean
  • bun run test — 702/702 pass
  • Live full run on bagaggio post-merge — expected wall-clock 6-8min, checks phase < 1min, console errors grouped

🤖 Generated with Claude Code

@JonasJesus42 JonasJesus42 changed the base branch from perf/parallel-viewports to main June 17, 2026 05:41
JonasJesus42 and others added 2 commits June 17, 2026 02:42
Building on 0.11.14's parallel-sides change:

- Wrap the outer `for (const viewport of viewports)` in
  runWithConcurrency, default 2. The standard mobile+desktop set
  now runs fully concurrent — 4 BrowserContexts simultaneously
  (mobile/prod + mobile/cand + desktop/prod + desktop/cand). Each
  viewport still runs its two sides in parallel via runOneSide.
  Expected ~40% additional collect speedup on top of 0.11.14.

- New `--max-viewport-concurrency <n>` flag (default 2). Memory-
  constrained machines can set 1 to revert to serial-viewport
  behavior; runs with a 3rd viewport (e.g. tablet) can cap how
  many run at once.

- Add a process-global semaphore in src/llm/client.ts capping
  concurrent LLM calls to 3. With 4 sides × recovery budget 3 in
  flight at peak, we could push 8-12 simultaneous LLM calls —
  past Anthropic tier-1's 4 RPS. Calls now queue instead of
  blowing up with 429s. Default 3 leaves headroom for the post-
  collect aggregate call to fire during peak concurrency.

Same `runOneSide` from 0.11.14 is now wrapped in `runOneViewport`
which Promise.all's the two sides; runWithConcurrency drives the
top level. Merge into allFlowCaptures/allPageCaptures still runs
single-threaded after each viewport's await resolves, so no race
on the shared accumulators or learned-selectors promotion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two changes that close the loop on user feedback after a 25m46s run:

1) `runAllChecks` ran ~27 checks sequentially (`for ... await check`),
   spending ~4m26s on a phase whose dominant cost is the slowest
   single check. Almost every check is a pure CPU aggregation over
   PageCapture data (string diffs, regex matches, console filtering);
   the 3 network-bound ones (seo-deep-audit, footer-links-health,
   plp-pagination) are I/O-bound and parallelize cleanly. Now uses
   Promise.all — phase wall-clock collapses to the longest single
   check (~30-60s expected on bagaggio).

2) consoleErrorsBaseline emitted one Issue per (page × error) pair,
   so the same domain-key mismatch leaking across home/search/etc
   produced 4-5 duplicate "Top issues" entries. Refactored to group
   by normalized error key across all page pairs and emit ONE issue
   per unique error with the affected-pages list inline. Direct
   response to user feedback: "console log não deveria ter um teste
   pra ele … fazer o dedup e descrever quais paginas tiveram aquele
   error". The schema-level Issue shape is unchanged.

Added test: dedupes the same error across pages into one issue.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@JonasJesus42 JonasJesus42 force-pushed the perf/inline-checks-and-console-dedup branch from c4e733c to f96e759 Compare June 17, 2026 05:42
@JonasJesus42 JonasJesus42 changed the title perf(checks): parallel execution + cross-page console dedup perf: parallel viewports + parallel checks + console dedup Jun 17, 2026
Observed on CI main run 27668261636: `setTimeout(r, 20)` returned at
19.99ms — below the test's `toBeGreaterThanOrEqual(20)` threshold.
Timer scheduling on busy GitHub Actions runners can fire ~1-3ms early
even when a 20ms timer was requested. Bumping the sleep to 30ms and
the threshold to 25ms keeps the "totalMs forgot to accumulate" check
strict while tolerating realistic scheduler jitter.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@JonasJesus42 JonasJesus42 merged commit b1ff65e into main Jun 17, 2026
2 checks passed
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