Repository navigation
perf: cut the cost of Jest's file indexing - #206
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this?
Harness's Jest preset now makes Jest's file indexing cheaper in three ways. Jest builds its file map in a single process instead of starting a pool of worker processes, it no longer walks build and cache output that can never contain tests, and it finds files itself instead of asking watchman.
Before this change, every cold run, and every run after a file changed, started
availableParallelism() - 1Jest worker processes (11 on a 12-core machine, 2 on a 3-vCPU CI runner) only to index files. Harness's runner is serial, so those workers never run tests. Jest also indexed Harness's own.harnesscache and native build output. Onapps/playground, 636 of the 736 indexed files were build or cache output, and without watchman Jest walked about 110,000 directory entries on every run.How does it work?
The preset sets
maxWorkers: 1, so Jest's haste map processes files in the main process. Test execution is unchanged because Harness's runner was already serial.The preset also adds
modulePathIgnorePatternsfor.harness,ios/Pods,ios/build,android/build,android/.gradle,android/app/buildandandroid/app/.cxx. Jest's crawler checks these patterns before descending into a directory, so it never reads those folders. Jest appends a project's ownmodulePathIgnorePatternsto the preset's.Finally, the preset sets
watchman: falsefor Jest. Asking watchman costs two CLI process spawns per run, and watchman still lists every file, including the build output, before Jest filters it. Once that output is skipped, Jest's own crawl is cheaper. Watch mode uses Jest's built-in file watcher instead. Metro is unchanged and still uses watchman. Projects can overridemaxWorkersandwatchmanin their own Jest config.Why is this useful?
Measured on
apps/playground, with the Harness runner stubbed so only Jest's own work is counted:Fewer processes and less crawling matter most on small CI runners, which have the fewest cores to spare next to Metro and the simulator.