Skip to content

perf: hand Biome and oxlint every file at once - #387

Closed
alexander-akait wants to merge 1 commit into
mainfrom
perf/cli-checks-one-run
Closed

alexander-akait wants to merge 1 commit into
mainfrom
perf/cli-checks-one-run

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Part of the performance series (#376–#386). Builds on #377 (the lintsOnce adapter hook), so this branch contains #377's commit and should land after it; the diff of its own is the last commit.

Problem

While webpack builds, the plugin hands a check its files in batches of 64, so the check can start early. For Biome and oxlint every batch is a process of its own, and each one:

  • reads the configuration again;
  • for Biome, also reads the project again for its project and types rules.

A one-shot build of 1,500 files started 16–21 of these processes, up to two at once, each wanting every core.

Change

Both adapters now say lintsOnce: () => true (the hook from #377), so they're handed every file once the module graph is done. That's one process per 500 files: 4 processes, one at a time. Watch rebuilds are unchanged, since they're a handful of files anyway.

Measured

1,500 .ts files, compiler.run. CPU is measured from /proc/self/stat, separating webpack's own process from the processes it started and waited for. Two runs each:

wall CPU, webpack CPU, processes processes started (at most at once)
Biome, main 4.7–5.1 s 7.7–8.4 s 2.9–3.0 s 16–17 (2)
Biome, this PR 5.0–5.1 s 7.7–7.9 s 2.15–2.2 s 4 (1)
oxlint, main 4.6–4.8 s 7.9–8.2 s 1.2–1.7 s 16–21 (2)
oxlint, this PR 4.4–4.7 s 7.5–7.9 s 0.26–0.31 s 4 (1)

Wall time is within noise: the processes ran alongside webpack before, and now run after it. The CPU the tools spend drops by a quarter for Biome and by about 80% for oxlint.

Tests

  • New: a case in test/lints-once.test.js checks that both adapters say they lint once. The mechanism itself is covered by perf: hand ESLint every file at once when it threads the lint itself #377's test.
  • Full suite: 320/320, global module path cleared, as on CI. eslint, tsc, prettier, cspell and lint:schema are clean.
  • README (Biome) and a changeset are updated, and types regenerated.

Generated by Claude Code

@linux-foundation-easycla

linux-foundation-easycla Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

CLA Not Signed

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <id+login@users.noreply.github.com> - it will locate your GitHub user by id part.
  2. Anything <login@users.noreply.github.com> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 25 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f6aa6bb0-ed70-43a2-a4ae-78ba05d00c51
📥 Commits

Reviewing files that changed from the base of the PR and between 0abded0 and 8a9d5ed.

📒 Files selected for processing: 7
  • .changeset/cli-checks-one-run.md
  • README.md
  • src/checks/biome.js
  • src/checks/oxlint.js
  • test/lints-once.test.js
  • types/checks/biome.d.ts
  • types/checks/oxlint.d.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.64%. Comparing base (dc3ff2f) to head (0b3e404).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #387      +/-   ##
==========================================
+ Coverage   99.62%   99.64%   +0.01%     
==========================================
  Files          19       19              
  Lines        5400     5626     +226     
==========================================
+ Hits         5380     5606     +226     
  Misses         20       20              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member Author

EasyCLA fails because the commits carry a Co-Authored-By: Claude trailer that maps to no GitHub account. It is not a code failure. Whether to drop the trailer or accept the check is for the maintainers to decide, so I haven't rewritten history.

This PR is stacked on #377 and should land after it.


Generated by Claude Code

Each lint of the Biome and oxlint checks is a process of its own that
reads the configuration and, for Biome, the project again. Handed in
batches of 64 while webpack built, a build of 1,500 files started 16-21
of them, two at a time.

Both adapters now say `lintsOnce` (#377), so they are handed every file
when the module graph is done: 4 processes, one at a time.

1,500 files, one-shot, CPU of the processes the build started:
Biome 2.9-3.0 s -> 2.15-2.2 s, oxlint 1.2-1.7 s -> 0.26-0.31 s. Wall
time unchanged (within noise).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01App18sYbe6Vf6HDCjCXbvf
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.

2 participants