[ci] Add size-balanced test sequencer for better shard distribution (#35458)
Jest's default test sequencer sorts alphabetically, causing large test files (eg ReactDOMFloat-test.js at 9k lines, ReactHooksWithNoopRenderer-test.js at 4k lines) to cluster in shard 3/5. This made shard 3/5 average 117s vs 77s for other shards, a 52% slowdown. I'm using filesize as a rough proxy for number of tests. This custom sequencer sorts tests by file size and distributes large files evenly across all shards instead of clustering them together. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35458). * __->__ #35458 * #35459
lauren committed
Jan 6, 2026 at 18:29 UTC
d6cae440e34c6250928e18bed4a16480f83ae18a
2 files changed
+29
scripts/jest/config.base.js
+1
@@ -2,6 +2,7 @@
2
3
module.exports = {
4
globalSetup: require.resolve('./setupGlobal.js'),
5
+ testSequencer: require.resolve('./sizeBalancedSequencer.js'),
6
modulePathIgnorePatterns: [
7
'<rootDir>/scripts/rollup/shims/',
8
'<rootDir>/scripts/bench/',
scripts/jest/sizeBalancedSequencer.js
new
+28
@@ -0,0 +1,28 @@
1
+'use strict';
2
+
3
+const Sequencer = require('@jest/test-sequencer').default;
4
+const fs = require('fs');
5
+
6
+class SizeBalancedSequencer extends Sequencer {
7
+ shard(tests, {shardIndex, shardCount}) {
8
+ const shards = Array.from({length: shardCount}, () => ({
9
+ tests: [],
10
+ size: 0,
11
+ }));
12
+ const sorted = [...tests].sort(
13
+ (a, b) => fs.statSync(b.path).size - fs.statSync(a.path).size
14
+ );
15
+
16
+ for (let i = 0; i < sorted.length; i++) {
17
+ const test = sorted[i];
18
+ const size = fs.statSync(test.path).size;
19
+ const smallest = shards.reduce((min, s) => (s.size < min.size ? s : min));
20
+ smallest.tests.push(test);
21
+ smallest.size += size;
22
+ }
23
+
24
+ return shards[shardIndex - 1].tests;
25
+ }
26
+}
27
+
28
+module.exports = SizeBalancedSequencer;