text:
jest 25 performance

💥 Regression Report
we upgraded jest from 24 to 25 and saw our unit tests go from taking 5min 23sec in jenkins to now over 11 minutes.  only a few snapshot tests broke in the upgrade, we -u'd them, but this is a severe regression imo.  please help me understand how we can fix this.  We clear cache in CI to ensure we always run the latest.
A clear and concise description of what the regression is.
run time went from 5:23, to 11:00
Last working version
24.8.0
Worked up to version:
24.8.0
Stopped working in version:
25.1.0
To Reproduce
sorry can't share our codebase
Steps to reproduce the behavior:
Expected behavior
A clear and concise description of what you expected to happen.
Link to repl or repo (highly encouraged)
Please provide either a repl.it demo or a minimal repository on GitHub.
Issues without a reproduction link are likely to stall.
Run npx envinfo --preset jest
Paste the results here:
  System:
    OS: macOS Mojave 10.14.6
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
  Binaries:
    Node: 10.16.0 - ~/.nvm/versions/node/v10.16.0/bin/node
    Yarn: 1.19.0 - ~/.nvm/versions/node/v10.16.0/bin/yarn
    npm: 6.13.6 - ~/.nvm/versions/node/v10.16.0/bin/npm

Sorry for the delay. Used npm-force-resolutions (which is doing the right thing) to lock micromatch to v3. Unfortunately, it didn't make my heap errors go away.
So for me, it's still jest-environment-jsdom-fourteen@1.0.0 to blame, as mentioned here: https://github.com/facebook/jest/issues/9457#issuecomment-579423330
Resolving jsdom to thirteen is what fixes it.

Does anyone who have experienced a performance degradation in 25 have issues that are not fixed by either using jsdom@13 or micromatch@3? Memory leak in JSDOM is being fixed (https://github.com/jsdom/jsdom/pull/2840 and various issues/PRs linked from it) and the regression in micromatch has been reported and is being worked on: https://github.com/micromatch/micromatch/issues/179.

Fixed version of JSDOM has been released, you can use it by installing jest-environment-jsdom-sixteen. @EvHaus could you verify it fixes your issue?

@SimenB my issue is probably not related, but I tried jest-environment-jsdom-sixteen vs using the default, and saw a 20s increase in runtime for the same test suite over repeated runs.

over using v15 (which is what ships with jest by default) and no other changes?

Fixed version of JSDOM has been released, you can use it by installing jest-environment-jsdom-sixteen. @EvHaus could you verify it fixes your issue?

Unfortunately still getting heap errors with jest-environment-jsdom-sixteen. The last stable working version of JSDom for me is  jest-environment-jsdom-thirteen.

Fixed version of JSDOM has been released, you can use it by installing jest-environment-jsdom-sixteen. @EvHaus could you verify it fixes your issue?

The environment works with our codebase, but we're still seeing an almost 100% regression in runtime. Anecdotally jest-environment-jsdom-sixteen seems to improve runs time performance by 10%ish only when using 25.1 vs 24.9

Hi @SimenB,
I've made the reproducible case here https://github.com/olebedev/jest-perf-issue. Please take a look. Below result to compare. /cc @joscha

Results
Benchmarks were run on MBP 2019, 32Gb RAM, i9-8950HK CPU @ 2.90GHz.

jest version
branch
time

24.9.0
master
348.077s

25.1.0
jest25
591.33s

In our case, where jest v25.1 were ~50% slower compared to v24.9, now the latest jest v25.2.0 is even further 20% slower compared to v25.1 🙈

@olebedev Woah, that's painful 😬
I'm getting similar numbers to you. If it's based on a real project I recommend using v8 coverage. It takes the runtime from 600s to 35s on my machine in your reproduction. The reason for the huge diff is probably that we don't try to instrument non-covered files with v8 coverage.
https://jestjs.io/docs/en/configuration#coverageprovider-string
Not sure why it's so slow... I'll try to find some time to look into it. It should at least not be any slower on v25 than v24

Do I understand the docs correctly that we can use v8 coverage together
with the ...-sixteen environment?
Cheers,
J
On Wed, 8 Apr 2020, 22:33 Simen Bekkhus, notifications@github.com wrote:

@olebedev https://github.com/olebedev Woah, that's painful 😬
I'm getting similar numbers to you. If it's based on a real project I
recommend using v8 coverage. It takes the runtime from 600s to 35s on my
machine in your reproduction. The reason for the huge diff is probably that
we don't try to instrument non-covered files with v8 coverage.
https://jestjs.io/docs/en/configuration#coverageprovider-string
Not sure why it's so slow... I'll try to find some time to look into it.
It should at least not be any slower on v25 than v24
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/jest/issues/9457#issuecomment-610931770, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AABN5BW6R45SS5Z5GXGFGF3RLRVJLANCNFSM4KK67LOA
.

Yes, either jest-environment-jsdom-sixteen, or the bundled jest-environment-node. Also note that it's only supported on node 10+, not node 8

jest-environment-jsdom-sixteen + v8 as coverage provider was worse by about 20% for us on jest 25.3.0, node 12.16. We're also trying to debug why our test performance got worse by about 80% going from jest 24 to 25.

@joual did you try the micromatch workaround (downgrade to 3.x)?

Having a similar experience here, test times (without coverage) double on v25 from 35-40 seconds to 80-90 and sometimes more. Tried locking micromatch on v3, no measurable difference. Fwiw, we have around 3k tests of which 58 are snapshot tests.
Attempted to downgrade jsdom but this seems to introduce lots of test breakage due to recent features we've been using. WIll see if I can get around this somehow and report back.

@SimenB The coverage collect job on prettier project is also very slow, can you check it? https://github.com/prettier/prettier/runs/579497097 Node.js 12 on ubuntu-latest collects coverage, other job don't.

Having a similar experience here, test times (without coverage) double on v25 from 35-40 seconds to 80-90 and sometimes more. Tried locking micromatch on v3, no measurable difference. Fwiw, we have around 3k tests of which 58 are snapshot tests.
Attempted to downgrade jsdom but this seems to introduce lots of test breakage due to recent features we've been using. WIll see if I can get around this somehow and report back.

Was experimenting with different jsdom versions today on jest@24 (which is v11 by default). Up to v14 everything seems to work fine, but as of v15 test runs take consistently 50-60% longer. Will see if I can get similar perf on jest@25 by downgrading jsdom to v14.

Having a similar experience here, test times (without coverage) double on v25 from 35-40 seconds to 80-90 and sometimes more. Tried locking micromatch on v3, no measurable difference. Fwiw, we have around 3k tests of which 58 are snapshot tests.
Attempted to downgrade jsdom but this seems to introduce lots of test breakage due to recent features we've been using. WIll see if I can get around this somehow and report back.

Was experimenting with different jsdom versions today on jest@24 (which is v11 by default). Up to v14 everything seems to work fine, but as of v15 test runs take consistently 50-60% longer. Will see if I can get similar perf on jest@25 by downgrading jsdom to v14.

JSDOM@16.2.2 has some memory fixes, @EvHaus could you try it out? Jest's own --detect-leaks finds leaks in previous versions, but not 16.2.2.
I've also landed some other improvements if you have lots of symlinks (which is super slow on windows), so if people could try out jest@25.5.3 that would be lovely 🙂

@SimenB What's the easiest way to test that? If I add jsdom@16.2.2 directly a devDependency Jest ignores that and uses whatever is bundled with jest-environment-jsdom which is 15.2.1 today.
How can I trick npm to ensure it's using the jsdom version I want?

Install jest-environment-jsdom-sixteen

Alpha published, so you can try jest@next - it comes with jsdom 16 out of the box

@SimenB Sorry, not much luck with jest@6.0.0-alpha.0 and its jsdom@16.2.2. Still getting many of these errors:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

And eventually the runner dies.
My details:
> npx envinfo --preset jest

  System:
    OS: macOS 10.15.4
    CPU: (8) x64 Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz
  Binaries:
    Node: 10.17.0 - ~/.nvm/versions/node/v10.17.0/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - ~/.nvm/versions/node/v10.17.0/bin/npm
  npmPackages:
    jest: ^26.0.0-alpha.0 => 26.0.0-alpha.0

Here are some of the full stacks returned from those:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d041 node::Abort() [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 2: 0x10003d24b node::OnFatalError(char const*, char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 3: 0x1001b8e25 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 4: 0x100586d82 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 5: 0x100589855 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 6: 0x1005856ff v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 7: 0x1005838d4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 8: 0x10059016c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 9: 0x1005901ef v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
10: 0x10055fb34 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
11: 0x1007e7e14 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
12: 0x3f82f50dbe3d
13: 0x3f82f5c630de
14: 0x3f82f5c94431
15: 0x3f82f5c7d3be
16: 0x3f82f5c4e98b
17: 0x3f82f5c3c38e

<--- Last few GCs --->

[50818:0x102804000]   189738 ms: Mark-sweep 1288.8 (1450.6) -> 1280.2 (1454.1) MB, 890.1 / 0.1 ms  (average mu = 0.181, current mu = 0.061) allocation failure scavenge might not succeed
[50818:0x102804000]   190673 ms: Mark-sweep 1292.8 (1454.1) -> 1282.9 (1457.6) MB, 856.2 / 0.2 ms  (average mu = 0.136, current mu = 0.084) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x3f82f50dbe3d]
Security context: 0x274d67c9e6e9 <JSObject>
    1: createImpl [0x274d6d9ba1b9] [/Users/evhaus/Git/zenhub/client/node_modules/jsdom/lib/jsdom/living/generated/HTMLInputElement.js:~47] [pc=0x3f82f5c630de](this=0x274d51911261 <Object map = 0x274dd51fe489>,globalObject=0x274d89d38609 <Window map = 0x274d2fe6c211>,constructorArgs=0x274d832134b1 <JSArray[0]>,privateData=0x274d832134d1 <Object map = 0x274d69...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d041 node::Abort() [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 2: 0x10003d24b node::OnFatalError(char const*, char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 3: 0x1001b8e25 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 4: 0x100586d82 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 5: 0x100589855 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 6: 0x1005856ff v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 7: 0x1005838d4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 8: 0x10059016c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 9: 0x1005901ef v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
10: 0x10055fb34 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
11: 0x1007e7e14 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
12: 0x2cea552dbe3d
13: 0x2cea55937c04
14: 0x2cea5592618b

<--- Last few GCs --->

[51263:0x102804000]    34292 ms: Mark-sweep 1332.4 (1452.5) -> 1320.5 (1453.5) MB, 902.6 / 0.0 ms  (average mu = 0.149, current mu = 0.104) allocation failure scavenge might not succeed
[51263:0x102804000]    35480 ms: Mark-sweep 1332.6 (1453.5) -> 1323.6 (1457.5) MB, 1049.3 / 0.0 ms  (average mu = 0.131, current mu = 0.116) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x2cea552dbe3d]
Security context: 0x1a4cb371e6e9 <JSObject>
    1: next [0x1a4ca627dcd1] [/Users/evhaus/Git/zenhub/client/node_modules/symbol-tree/lib/TreeIterator.js:~16] [pc=0x2cea55937c04](this=0x1a4c807c75b1 <TreeIterator map = 0x1a4c38b8a9c9>)
    2: shadowIncludingInclusiveDescendantsIterator(aka shadowIncludingInclusiveDescendantsIterator) [0x1a4ca627a641] [/Users/evhaus/Git/zenhub/client/node_modules/jsdom/li...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d041 node::Abort() [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 2: 0x10003d24b node::OnFatalError(char const*, char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 3: 0x1001b8e25 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 4: 0x100586d82 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 5: 0x100589855 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 6: 0x1005856ff v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 7: 0x1005838d4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 8: 0x10059016c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 9: 0x1005901ef v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
10: 0x10055fb34 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
11: 0x1007e7e14 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
12: 0x3e0d8aedbe3d
13: 0x3e0d8b35eedc

<--- Last few GCs --->

[51519:0x102804000]    28074 ms: Mark-sweep 1324.5 (1445.0) -> 1315.7 (1449.0) MB, 760.4 / 0.0 ms  (average mu = 0.182, current mu = 0.080) allocation failure scavenge might not succeed
[51519:0x102804000]    28906 ms: Mark-sweep 1328.5 (1449.0) -> 1317.7 (1452.0) MB, 770.4 / 0.0 ms  (average mu = 0.129, current mu = 0.074) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x3e0d8aedbe3d]
Security context: 0x3611d141e6e9 <JSObject>
    1: queueMutationRecord(aka queueMutationRecord) [0x361185f32321] [/Users/evhaus/Git/zenhub/client/node_modules/jsdom/lib/jsdom/living/helpers/mutation-observers.js:~33] [pc=0x3e0d8b35eedc](this=0x361116e826f1 <undefined>,type=0x3611aa0a3681 <String[9]: childList>,target=0x36110b275a91 <EventTargetImpl map = 0x3611a254a2f1>,name=0x361116e822b1 <null>,name...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x10003d041 node::Abort() [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 2: 0x10003d24b node::OnFatalError(char const*, char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 3: 0x1001b8e25 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 4: 0x100586d82 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 5: 0x100589855 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 6: 0x1005856ff v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 7: 0x1005838d4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 8: 0x10059016c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
 9: 0x1005901ef v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
10: 0x10055fb34 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
11: 0x1007e7e14 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/evhaus/.nvm/versions/node/v10.17.0/bin/node]
12: 0x8d8aedbe3d
<--- Last few GCs --->

[51526:0x102804000]    33125 ms: Mark-sweep 1318.6 (1425.0) -> 1317.7 (1424.0) MB, 874.8 / 0.0 ms  (average mu = 0.126, current mu = 0.038) allocation failure scavenge might not succeed
[51526:0x102804000]    33136 ms: Scavenge 1318.5 (1424.0) -> 1318.0 (1424.5) MB, 3.8 / 0.0 ms  (average mu = 0.126, current mu = 0.038) allocation failure
[51526:0x102804000]    33148 ms: Scavenge 1318.7 (1424.5) -> 1318.2 (1425.0) MB, 4.2 / 0.0 ms  (average mu = 0.126, current mu = 0.038) allocation failure

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x8d8aedbe3d]
    1: StubFrame [pc: 0x8d8ae8d40b]
    2: ConstructFrame [pc: 0x8d8ae8cfa3]
Security context: 0x3324ecd9e6e9 <JSObject>
    3: new NodeImpl(aka NodeImpl) [0x3324c2083e11] [/Users/evhaus/Git/zenhub/client/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:~125] [pc=0x8d8b357fd4](this=0x332437582801 <the_hole>,globalObject=0x3324b10f98e9 <Window map = 0x3324649cf0a1>,args=0x3324b1841471 <JSArray[0]>,...

Too bad 😞 Is that with or without coverage?

That was without coverage. Should have clarified.
Do you think that I'm running a fairly old version of Node (v10) would be factor in this?

You can try using newer versions, if nothing else it'd be an interesting data point. Other things to try is to try to make a heap dump right before it dies. What's on the heap?

It's interesting that nobody mentioned that micromatch@4 doesn't cache regexps anymore (see https://github.com/micromatch/micromatch/pull/151 and https://github.com/facebook/jest/pull/10131 introduces missing caching on jest side.
For me downgrade to micromatch@3 and upgrade to jest-environment-jsdom-sixteen saved 50% of time.
But with jest 26 and built-in jsdom Im still getting leaks error when run jest with --detectLeaks.

https://github.com/facebook/jest/pull/10131 is merged!! <3

Released in 26.1.0, very interested in hearing if it helps folks

@SimenB thanks a lot for the release! unfortunately on our side we're still facing a huge difference:
current:
os: osx
node: 12.6.1
jest: 24.9
-----------------
174 test suites
823 tests
322 snapshots
-----------------
done in 23.569s

on every version higher than 24.9
os: osx
node: 12.6.1
jest: 26.1.0
-----------------
174 test suites
823 tests
322 snapshots
-----------------
done in 133.763s

both with fresh caches and after a complete reinstall of all node modules. untouched configs.
running tests on watch mode it takes more than 3min on my machine to determine which tests to run. i can't really isolate the issue for a reproduction but if you give me some advices what to test, i'd be very interested. thanks for all the work you put into that!

@SimenB
For prettier project, still slow than v24 when collecting coverage.

https://github.com/prettier/prettier/pull/8636

I can confirm that versions 25 and 26 performances are lower than 24 on Bitbucket Pipeline. I've also noticed that the slowness increases with coverage enabled. Version 25 gets even worse compared to 26 and the pipeline crashes due the memory consume.

@SimenB I did a git bisect to find out where the performance regression between 24.9 and 25.1 was introduced. I used the prettier tests because they run without modification all the way from 24.9 to 26.1.
I compared the accumulated runtime of three runs of the js subset (to safe some time) with disabled cache. More specially the command I use was (yarn run jest --no-cache tests/js/) with node 10.19. because node 10 was the recommended version for 24.9.
Results:
24.9.0-dev 3cdbd556948b4974b2cc23178977eb159d343df8 151.84s <- Good
25.1.0-dev 5dcc48075f22d581864f381f20bc8b257d2a73cd 223.29s <- Bad
24.9.0-dev bf6109591365a2b71c7b642fa33ed06d3db6cb26 122.58s
24.9.0-dev 77c3ceedfd61ddc841e11fec7b76e540924d3e60 120.42s
24.9.0-dev 30e08e9ae7d7d78f40df757c2ec4b49357285eda 221.28s
24.9.0-dev ad5377333daf6716af3465bba39f86b7db485e2b 222.33s
24.9.0-dev 8ddadfca76eb3fb979df81033d3d0ff564c415d6 120.32s
24.9.0-dev 966f22f2a08d9ac9300b6964ab91c4e75dba4761 120.46s
24.9.0-dev b9084101189639524863e15ef7557ea6bc6704b9 119.87s
24.9.0-dev 1d8245d77d47b4198d51e55da87893d7dfe1a759 129.93s

ad5377333daf6716af3465bba39f86b7db485e2b is the first bad commit
commit ad5377333daf6716af3465bba39f86b7db485e2b
Author: Simen Bekkhus <sbekkhus91@gmail.com>
Date:   Mon Dec 2 23:20:16 2019 +0100

    feat: add support for `compileFunction` allowing us to avoid the module wrapper (#9252)

Since there is a fallback if compileFunction is not defined I removed the compileFunction branch from ad5377333daf6716af3465bba39f86b7db485e2b which restored the performance.
Looking at 26.1 the code has moved around a bit but compileFunction and the fallback are still there. So:
26.1.0-dev 817d8b6aca845dd4fcfd7f8316293e69f3a116c5 242.99s <- with compileFunction
26.1.0-dev 817d8b6aca845dd4fcfd7f8316293e69f3a116c5 151.61s <- without compileFunction

i.e. removing the compileFunction branch (patch) brings 26.1 back to the runtime of 24.9. I’m sure that is not the solution, but at least we have something to work with.

As another data point, our jest suite currently takes around 2767 seconds with jest@24.8.0 and in our update MR it takes around 3497 seconds, an increase around 27%.
Thanks for all the great work, jest team, I hope that the detective skills of @wurstbonbon can help you fixing that regression!

@wurstbonbon thanks for taking the time to dig! Very interesting that compileFunction is slower... That should mean that you can just use a custom test environment instead of applying a patch.
const NodeEnv = require('jest-environment-node');

class MyNodeEnv extends NodeEnv {}

MyNodeEnv.prototype.compileFunction;

module.exports = MyNodeEnv;

(and the same for jsdom env). Can you confirm?

It being such a bottleneck sounds weird though - Node itself switched to using it 18 months ago: https://github.com/nodejs/node/pull/21573. So it's probably something weird we're doing on our side

@SimenB i just tried something similar to that custom env and it looks like it was a little better (but still slower than jest 24).
I had to do MyNodeEnv.prototype.getVmContext = null;, though, because I'm testing with jest 26, and it looks like it checks for if (typeof this._environment.getVmContext === 'function') { now. Not sure if this could cause other issues, though.
These are the results i'm seeing after a few runs:
Jest 26 w/testEnvironment: "node" => ~280s
Jest 26 w/custom test environment => ~210s
Jest 24 => ~160s
Let me know if i can help with any other information or something else!

As expected the custom env results in the same speedup for prettier.
I've also tried it on our codebase where the difference is ~270s vs ~200s so only about 25% and not 40% reduction. Unfortunately I can't run our tests with jest 24 because we rely on the new modern timers mocking.

I missed a delete in my example above, sorry about that.

I wonder if it's enough to just cache the compiled functions manually - could you try to apply this patch? (both transpiled JS and the TS source included here)

diff --git i/packages/jest-runtime/build/index.js w/packages/jest-runtime/build/index.js
index 1d094a6dc0..f6d059caa3 100644
--- i/packages/jest-runtime/build/index.js
+++ w/packages/jest-runtime/build/index.js
@@ -267,6 +267,7 @@ const getModuleNameMapper = config => {
 const unmockRegExpCache = new WeakMap();
 const EVAL_RESULT_VARIABLE = 'Object.<anonymous>';
 const runtimeSupportsVmModules = typeof _vm().SyntheticModule === 'function';
+const compiledFunctionCache = new Map();
 /* eslint-disable-next-line no-redeclare */

 class Runtime {
@@ -1169,23 +1170,30 @@ class Runtime {
       value: this._createRequireImplementation(localModule, options)
     });
     const transformedCode = this.transformFile(filename, options);
-    let compiledFunction = null; // Use this if available instead of deprecated `JestEnvironment.runScript`
+    let compiledFunction = undefined; // Use this if available instead of deprecated `JestEnvironment.runScript`

     if (typeof this._environment.getVmContext === 'function') {
       const vmContext = this._environment.getVmContext();

       if (vmContext) {
-        try {
-          compiledFunction = (0, _vm().compileFunction)(
-            transformedCode,
-            this.constructInjectedModuleParameters(),
-            {
-              filename,
-              parsingContext: vmContext
-            }
-          );
-        } catch (e) {
-          throw (0, _transform().handlePotentialSyntaxError)(e);
+        const params = this.constructInjectedModuleParameters();
+        const cacheKey = transformedCode + params;
+        compiledFunction = compiledFunctionCache.get(cacheKey);
+
+        if (!compiledFunction) {
+          try {
+            compiledFunction = (0, _vm().compileFunction)(
+              transformedCode,
+              params,
+              {
+                filename,
+                parsingContext: vmContext
+              }
+            );
+            compiledFunctionCache.set(cacheKey, compiledFunction);
+          } catch (e) {
+            throw (0, _transform().handlePotentialSyntaxError)(e);
+          }
         }
       }
     } else {
@@ -1194,13 +1202,13 @@ class Runtime {
       const runScript = this._environment.runScript(script);

       if (runScript === null) {
-        compiledFunction = null;
+        compiledFunction = undefined;
       } else {
         compiledFunction = runScript[EVAL_RESULT_VARIABLE];
       }
     }

-    if (compiledFunction === null) {
+    if (!compiledFunction) {
       this._logFormattedReferenceError(
         'You are trying to `import` a file after the Jest environment has been torn down.'
       );
diff --git i/packages/jest-runtime/src/index.ts w/packages/jest-runtime/src/index.ts
index 522adabd1e..8958a4cef8 100644
--- i/packages/jest-runtime/src/index.ts
+++ w/packages/jest-runtime/src/index.ts
@@ -137,6 +137,8 @@ type RunScriptEvalResult = {[EVAL_RESULT_VARIABLE]: ModuleWrapper};

 const runtimeSupportsVmModules = typeof SyntheticModule === 'function';

+const compiledFunctionCache = new Map<string, ModuleWrapper>();
+
 /* eslint-disable-next-line no-redeclare */
 class Runtime {
   private _cacheFS: StringMap;
@@ -1000,24 +1002,29 @@ class Runtime {

     const transformedCode = this.transformFile(filename, options);

-    let compiledFunction: ModuleWrapper | null = null;
+    let compiledFunction: ModuleWrapper | undefined = undefined;

     // Use this if available instead of deprecated `JestEnvironment.runScript`
     if (typeof this._environment.getVmContext === 'function') {
       const vmContext = this._environment.getVmContext();

       if (vmContext) {
-        try {
-          compiledFunction = compileFunction(
-            transformedCode,
-            this.constructInjectedModuleParameters(),
-            {
+        const params = this.constructInjectedModuleParameters();
+
+        const cacheKey = transformedCode + params;
+
+        compiledFunction = compiledFunctionCache.get(cacheKey);
+
+        if (!compiledFunction) {
+          try {
+            compiledFunction = compileFunction(transformedCode, params, {
               filename,
               parsingContext: vmContext,
-            },
-          ) as ModuleWrapper;
-        } catch (e) {
-          throw handlePotentialSyntaxError(e);
+            }) as ModuleWrapper;
+            compiledFunctionCache.set(cacheKey, compiledFunction);
+          } catch (e) {
+            throw handlePotentialSyntaxError(e);
+          }
         }
       }
     } else {
@@ -1028,13 +1035,13 @@ class Runtime {
       );

       if (runScript === null) {
-        compiledFunction = null;
+        compiledFunction = undefined;
       } else {
         compiledFunction = runScript[EVAL_RESULT_VARIABLE];
       }
     }

-    if (compiledFunction === null) {
+    if (!compiledFunction) {
       this._logFormattedReferenceError(
         'You are trying to `import` a file after the Jest environment has been torn down.',
       );

I though this might do the trick.
const params = this.constructInjectedModuleParameters();
const cacheKey = transformedCode + params;
const cachedData = compileFunctionCache.get(cacheKey);

try {
  compiledFunction = (0, _vm().compileFunction)(
    transformedCode,
    params,
    {
      filename,
      parsingContext: vmContext,
      cachedData,
      produceCachedData: !cachedData,
    },
  );

  if (compiledFunction.cachedDataProduced) {
    compileFunctionCache.set(cacheKey, compiledFunction.cachedData);
  }
} catch (e) {
  throw (0, _transform().handlePotentialSyntaxError)(e);
}

It improves performance a little but Script is still a lot faster.

Tried the recommendation from @SimenB: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33252/diffs?commit_id=6d633c88caf70f712fa0ccaac42d952976161ec6
While it did improve performance a bit, it is still considerably slower than on jest 24.x:

Jest 24.x: 2580 seconds total runtime of our jest tests
Jest 26.x: 3166 seconds total runtime of our jest tests

Opened up https://github.com/nodejs/node/issues/35375 upstream about the issue found by @wurstbonbon

@SimenB are you aware of any viable alternatives to micromatch? That repo has been silent for over half a year now, and major issues affecting Jest like https://github.com/micromatch/micromatch/issues/179 are still open.

Not really, it's what most libraries use. Could look at e.g. minimatch, but I doubt it'd be viable

@SimenB What makes minimatch better than all the alternatives?

Based on the feedback in the issue I've opened, I'm thinking we should revert to using Script for now as it seems it's gonna need a bit of work in Node to fix it there.
@leipert @wurstbonbon or anyone else, can you try this patch in your node_modules/jest-runtime/build/index.js?

diff --git i/packages/jest-runtime/build/index.js w/packages/jest-runtime/build/index.js
index 851d8e12cd..7235082546 100644
--- i/packages/jest-runtime/build/index.js
+++ w/packages/jest-runtime/build/index.js
@@ -1170,35 +1170,24 @@ class Runtime {
       value: this._createRequireImplementation(localModule, options)
     });
     const transformedCode = this.transformFile(filename, options);
-    let compiledFunction = null; // Use this if available instead of deprecated `JestEnvironment.runScript`
+    let compiledFunction = null;
+    const script = this.createScriptFromCode(transformedCode, filename);
+    let runScript = null; // Use this if available instead of deprecated `JestEnvironment.runScript`

     if (typeof this._environment.getVmContext === 'function') {
       const vmContext = this._environment.getVmContext();

       if (vmContext) {
-        try {
-          compiledFunction = (0, _vm().compileFunction)(
-            transformedCode,
-            this.constructInjectedModuleParameters(),
-            {
-              filename,
-              parsingContext: vmContext
-            }
-          );
-        } catch (e) {
-          throw (0, _transform().handlePotentialSyntaxError)(e);
-        }
+        runScript = script.runInContext(vmContext, {
+          filename
+        });
       }
     } else {
-      const script = this.createScriptFromCode(transformedCode, filename);
-
-      const runScript = this._environment.runScript(script);
+      runScript = this._environment.runScript(script);
+    }

-      if (runScript === null) {
-        compiledFunction = null;
-      } else {
-        compiledFunction = runScript[EVAL_RESULT_VARIABLE];
-      }
+    if (runScript !== null) {
+      compiledFunction = runScript[EVAL_RESULT_VARIABLE];
     }

     if (compiledFunction === null) {

I'll need to tweak how v8 code coverage works, but I'll try to open a PR tomorrow or next week.

I tested out the patch to use Script on our test suites and here's the result I came to
Time is in min:sec

Name
Suite 1
Suite 2
Suite 3
Suite 4

jest 24
3:25
3:30
3:29
0:53

jest 26 patched
3:32
4:36
3:48
0:53

jest 26 unpatched
5:10
6:12
5:11
1:07

26 patched vs 24
4%
31%
9%
1%

26 unpatched vs 24
52%
76%
49%
27%

26 patched vs unpatched
46%
35%
36%
25%

Iteration
Suite 1
Suite 2
Suite 3
Suite 4

jest 24 - 1
2:58
3:37
3:33
0:47

jest 24 - 2
3:18
3:34
3:32
0:51

jest 24 - 3
3:27
3:08
3:48
0:59

jest 24 - 4
3:37
3:44
3:38
0:53

jest 24 - 5
3:45
3:31
2:56
0:55

jest 26 patched - 1
3:42
4:31
4:08
0:57

jest 26 patched - 2
3:11
4:18
3:28
0:57

jest 26 patched - 3
3:55
5:12
3:19
0:55

jest 26 patched - 4
3:22
4:25
4:20
0:46

jest 26 unpatched - 1
4:30
6:12
4:28
1:08

jest 26 unpatched - 2
5:16
6:17
5:18
1:05

jest 26 unpatched - 3
5:46
6:07
5:49
1:09

All tests ran on same commit & similar test environment (Azure DevOps Hosted Ubuntu 18)
I only took the time taken for running jest on my test suites.
Most of my suites are similar in nature (all backend unit tests)
From what I can tell, the patch to use Script does make a huge difference on the perf.
I can't tell if the slowdown on Suite 2 is an outlier or a real regression (only did 4 runs).
It does look like there's still a perf regression, but not as bad

still interesting that v26 still doesn't improve on v24...

Thanks @Cellule! That's good enough for me - I'll put together a PR when I have some time

Awesome stuff! That leaves only the Micromatch issue then, hopefully that repo will come under active maintenance again.

BTW, there is also perf regression in JSDOM I assume. As I did such tests on a big web project.
And it looked like that.
Jest 24  (testEnvironment: "jsdom") (no rewires latest CRA)
144.014s

Jest 24 (testEnvironment: "jest-environment-jsdom-sixteen") (rewire latest CRA that changes testEnvironment)
409.473s (also few failed tests)

Jest 26 (testEnvironment: "jsdom") (no rewires latest CRA) so old jsdom? Whatever is the default for Jest 26 I assume? (I used react-app-rewired to rewire jest config and pnpmfile.js to override what version of Jest was installed with `react-scripts` as it still ships Jest 24 (like resolutions in yarn))
310.275s

Jest 26 (testEnvironment: "jest-environment-jsdom-sixteen") (rewire latest CRA that changes testEnvironment + pnpmfile.js)
over 1200s+ (some tests failed plus test run just stuck forever)

Surely this is a super vague and unstable performance report I must stay, but I think every input helps :)

https://github.com/facebook/jest/releases/tag/v26.5.0 has the vm.Script change discussed here

Preliminary results on the same test suite:
Jest 26.5
Cold: 85.222
Hot:  41.399
Jest 26.4:
Cold:  90.213
Hot: 47.408

And here are the results with my test suite:
Jest 26.5
Cold: 149s
Jest 26.4
Cold: 226s

Great news 🙂 I think we're back to just the micromatch regression, then

If you guys are using npm-force-resolutions to forcely install micromatch 3. It may not work in jest@26.5.0
// package.json
  ...
  "preinstall": "npx npm-force-resolutions",
  ..
  "resolutions": {
    "micromatch": "^3.0.0"
  }

Error when run test:
TypeError: _micromatch(...).default.scan is not a function
    at globs.map.glob (/home/travis/build/removed/node_modules/jest-util/build/globsToMatcher.js:65:47)
    at Array.map (<anonymous>)
    at globsToMatcher (/home/travis/build/removed/node_modules/jest-util/build/globsToMatcher.js:61:26)
    at new SearchSource (/home/travis/build/removed/node_modules/@jest/core/build/SearchSource.js:197:49)
    at contexts.map.context (/home/travis/build/removed/node_modules/@jest/core/build/runJest.js:265:16)
    at Array.map (<anonymous>)
    at runJest (/home/travis/build/removed/node_modules/@jest/core/build/runJest.js:264:34)
    at startRun (/home/travis/build/removed/node_modules/@jest/core/build/cli/index.js:479:35)
    at runWithoutWatch (/home/travis/build/removed/node_modules/@jest/core/build/cli/index.js:494:10)
    at _run10000 (/home/travis/build/removed/node_modules/@jest/core/build/cli/index.js:416:13)
npm ERR! Test failed.  See above for more details.

@SimenB Thank you very much for the update. It saves us 20% of running time on Travis after updating to jest@26.5.0

Our results:

jest v26.5

323.98s
321.24s

jest v24.9

262.17s
275.96s

Thanks @SimenB! This is amazing. Our results for our ~22000 tests in ~2000 suites:

Jest 24.x: 2864 s
Jest 26.5.2: 2967 s

which is about 3% slower and thus in the margin of error, compared to the ~27% we saw before. Thank you, now we just need to merge: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33252#note_425616404

Just wanted to note that all of the "heap out of memory" issues that I was having before are gone after upgrading to Jest 26.5.2 and Node 14 (was on Node 10 before). Not sure how much of the problem was caused by Jest vs. by Node, but if others are seeing similar problems try upgrading to both.

If somebody is interested, I have created a DOM that has very good performance in comparison to JSDOM. It has support for Jest.

Operation
JSDOM
Happy DOM

Import / Require
333 ms
45 ms

Parse HTML
256 ms
26 ms

Serialize HTML
65 ms
8 ms

Render custom element
214 ms
19 ms

querySelectorAll('tagname')
4.9 ms
0.7 ms

querySelectorAll('.class')
6.4 ms
3.7 ms

querySelectorAll('[attribute]')
4.0 ms
1.7 ms

querySelectorAll('[class~="name"]')
5.5 ms
2.9 ms

querySelectorAll(':nth-child(2n+1)')
10.4 ms
3.8 ms

Link to project:
https://github.com/capricorn86/happy-dom/

@capricorn86 Looks nice. Is it spec compliant?

@capricorn86 Looks nice. Is it spec compliant?

The functionality that has been implemented has been implemented according to specs, but there is no detailed overview of which specs that are covered yet. I am thinking about adding that. However, all functionality is covered by unit tests.
The initial goal of the DOM was to be able to render web components server side with good performance, as I needed it for some other projects.

FWIW, I just tried bumping our project from react-scripts@3 with Jest 24.9, to @react-scripts@4 with Jest 26.6.
Our server API test suite had previously been executing in about 180-190 seconds.  After switching to Jest 26.6, it was consistently taking about 220 seconds.  I even tried forcing resolution of minimatch to 4.0.2.  Switching the test runner to jest-circus seemed to knock off a couple seconds, but overall, 26.6 seems noticeably slower.

react-scripts@4 uses jest-circus by default, fwiw. It's also micromatch we use, not minimatch. Seems we've broken rolling back micromatch via #10131, however, so not as easy to test anymore

@SimenB : we've got a weird migration setup atm - it's a legacy MEAN / AngularJS app that I converted to build using CRA.  The test config is all our own, vs the built-in CRA Jest config - we're just taking advantage of the fact that CRA comes with Jest as a dependency.
I don't have my work box in front of me atm, so now I can't remember if I actually meant micromatch or if I really focused on the wrong package name there :)  I'll have to look at it again next week.

After giving up on trying to remediate our perf issues and making the final switch from v24 to v26 I noticed that v26 runs a lot slower in iTerm than in macOS's default terminal. On a set of 6500 tests I consistently get the following results:

v24, Terminal: ~90s
v24, iTerm2: ~90s
v26, Terminal: ~110s
v26, iTerm2: ~150s

This blew my mind a little bit after months of trying various things to sort out the slowdown. Any chance anyone else with perf issues on a mac can try this out?

@pleunv I believe this may be related: https://github.com/facebook/jest/pull/9294. I noticed that hyperlinks slow down iTerm2 on my machine, making it choppy. But haven't investigated the overall speed of execution, nor found another person that had issues with it.

Eureka. Searching for "iTerm" brought me to this PR. I had noticed these underlines before and didn't realize they were hyperlinks. After seeing that PR I disabled hyperlinks which brought my runtime down to 130s. After applying the code from the PR and removing the hyperlinks I'm back down to 120s.
Any chance that PR can get put back in?

@pleunv I'll try to find some time this week to bring it back. Although the real deal would be to fix this for iTerm, as other terminals e.g. on Linux have no issues with hyperlinks. Would you mind to file an issue to the iTerm project?

I just made this change and it gave me 1s for a single test file. And you can still click on the url, it's just no longer underlined.

This might be huge for larger runs. ❤

@pleunv I'll try to find some time this week to bring it back. Although the real deal would be to fix this for iTerm, as other terminals e.g. on Linux have no issues with hyperlinks. Would you mind to file an issue to the iTerm project?

I've created an issue here (they're on GitLab). If anyone has additional details or a repro project, feel free to add.

I'm still seeing a 30% slowdown as well jumping from 23.6 to 26.6.
23.6.0
cold 29.9
warm 15.4

26.6.3
cold 40.6
warm 24.0

It seems like the setup is problematic; while it would take ~4 seconds for the first test to complete with 23.6, it'll now take ~10 seconds.
No obvious difference in speed between iTerm and Terminal, though I do notice the glitchy/flashy output @pleunv mentioned on iTerm.
If this seems like something people still have an appetite for debugging I can try to put together a repro repo.

We recently updated to jest 26 + jest-circus so that we could add some light instrumentation to our test suite. We initially had individual transactions for each runScript, but it was being called hundreds (thousands?) of times and made it hard to read:

The Missing instrumentation block is all of the runScript calls which amounts to more than 50% of the test suite duration. (Our tests may also be leaky as the test duration increases for each run).

I'm also getting heap errors since upgrading to jest@25 and up.
I made a repo that contains a minimal reproduction of the error: https://github.com/gjgd/minimal-cipher-jest-bug
git clone git@github.com:gjgd/minimal-cipher-jest-bug.git
cd minimal-cipher-jest-bug
cd doesnt-work
npm i
npm t

This is the full error: https://github.com/gjgd/minimal-cipher-jest-bug/runs/1506646882#step:5:15
The only solution that I found so far was to downgrade to jest@24

Hi, @billyvg ! What is a soft that you used to monitor tests? https://github.com/facebook/jest/issues/9457#issuecomment-736152077

@Lertis https://sentry.io

@billyvg already found it, but thanks for an answer. Cannot understand how to monitor tests there, any guides/videos/topics?

@Lertis It's a bit experimental, but here's what we did: https://github.com/getsentry/sentry/pull/22237

@SimenB Regression in micromatch was fixed in 4.0.4, would it be possible to bump the dependency and see if it improves the performance in jest cases that regressed before?

It's in semver range, so you can update locally

@SimenB Yes, but considering that it's an important fix, wouldn't it make sense to force update globally?

I checked on my codebase and cannot see any performance difference with micromatch@4.0.4

@atsikov Thanks for checking! Guess it only makes difference when there are excluded tests.

@kibertoad you are right, I should have checked changes in micromatch before testing.
I remember micromatch was mentioned in the discussion, so I had an impression that there was a performance fix, and not just a regression which is likely caused https://github.com/facebook/jest/issues/9464

I'm not seeing an improvement with 4.0.4, but as has been discussed here and elsewhere that was probably not the cause of the regression in the first place.

My team upgraded Jest from 24 to 26 and ran into similar performance woes, regardless of whether we're collecting coverage (our tests were taking ~30-40% longer).  I've tried a few things mentioned in this thread:

micromatch@4.04 - no perceivable change for us
jest-environment-jsdom@24 - performance improved, in line with what we were experiencing with Jest 24
Trying the various jest-environment-jsdom-{version} packages as test environments

Baseline performance with Jest 24:
Test Suites: 348 passed, 348 total
Tests:       3948 passed, 3948 total
Snapshots:   0 total
Time:        532.623s
Ran all test suites.

Performance after upgrading to Jest 26 💥:
Test Suites: 348 passed, 348 total
Tests:       3948 passed, 3948 total
Snapshots:   0 total
Time:        748.671 s
Ran all test suites.

Performance with Jest 26 and jest-environment-jsdom-fourteen:
Test Suites: 348 passed, 348 total
Tests:       3948 passed, 3948 total
Snapshots:   0 total
Time:        493.382 s
Ran all test suites.

Performance with Jest 26 and jest-environment-jsdom-fifteen 💥:
Test Suites: 348 passed, 348 total
Tests:       3948 passed, 3948 total
Snapshots:   0 total
Time:        757.684 s
Ran all test suites.

I'm not exactly sure what it is about JSDOM 15/16 that is causing this for us, but it seems we don't have an issue with JSDOM 14.

I was able to fix and resolve the OOM errors we were having by doing the following:

Adding a forced async timeout for tests which performed heavy DOM manipulation.

// We have hundreds of tests that use this
beforeEach(async () => {
    // Inject a giant HTML string into the DOM to simulate a real website
    document.documentElement.innerHTML = TEST_SUITE.dom;

    // THIS WAS THE MOST IMPORTANT FIX
    // Without this, memory would never get released between test suites and would reach the Node memory ceiling
    await new Promise((resolve) => {
        setTimeout(() => resolve(), 1);
    })
});

Cleaning up and fixing all "Warning: An update to [...] inside a test was not wrapped in act(...)." errors being reported in the tests
Cleaning up and fixing all "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application." errors being reported in the tests
Setting as many of our tests as possible to use @jest-environment node. Majority of our tests needed the DOM, but at least some of them could use the Node environment. This sped them up a lot.
Upgrading to the latest Jest 27+ version

After this, all the JavaScript heap out of memory went away and the run time of Jest 24 was comparable to Jest 27. Maybe even a little bit faster.
2 big lesson for us were to:

Stop ignoring all the warnings and errors reported in the Jest output. All devs are now asked to be extra mindful of this.
Run node --expose-gc ./node_modules/.bin/jest --runInBand --logHeapUsage periodically to check on how much memory is used in our test suites and ensure that it doesn't indicate constant growth

Hope this can help others who are having issues.

I'm not exactly sure what it is about JSDOM 15/16 that is causing this for us, but it seems we don't have an issue with JSDOM 14.

A few weeks ago I played around with replacing babel with @swc/jest just to see how it would impact test performance and it barely made a dent. I don't know what happened inside JSDOM after v14 but it's gotten unbearably slow.

I tried https://github.com/capricorn86/happy-dom as JSDOM alternative, that was a few month ago. I did not support everything when need and I had no time to take a deeper look into it. However the tests which ran were not significantly faster. (Our setup is very complex.)
Depending on your setup and needs it might be a viable alternative.

As an addendum, I suppose we can say that Jest performance is pretty great as of Jest 29 (at least).

Hello 'github-actions[bot]',
Thank you for contacting us!  The Notable office is currently closed in observance of the Presidents' Day holiday.
We will resume normal business hours on Tuesday, February 20th, from 9am to 9pm EST and look forward to assisting you at that time.

Best Regards,
The Notable Team

Who knew that the achilles heel of ActionsBot was vacation auto-replies.

Hello 'Christopher,
Thank you for contacting us!  The Notable office is currently closed in observance of the Presidents' Day holiday.
We will resume normal business hours on Tuesday, February 20th, from 9am to 9pm EST and look forward to assisting you at that time.

Best Regards,
The Notable Team

authors: 7rulnik AndrewSouthpaw Cellule EvHaus Lertis RIP21 SimenB atsikov beckerei benmonro billyvg capricorn86 csvan emilio-notable falkenhawk fisker gjgd joscha joual kgregory kibertoad kkckkc kylemh leipert markerikson milesj nvh95 olebedev pleunv thymikee tsantos84 wurstbonbon zanettin


text:
fix: pass matcher context to asymmetric matchers

Summary
~This exposes that asymmetric matchers are not called with this - which IMO is a bug. For now I've stuck a @ts-ignore there, but we should fix it~
Asymmetric matchers were not called with matcher context - meaning they didn't have access to this.equals, this.utils etc..
First commit makes TypeScript highlight that as an error, second commit fixes passing this.

Test plan
Green CI

Codecov Report

Merging #11926 (010797a) into main (b9fc8ac) will decrease coverage by 0.00%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main   #11926      +/-   ##
==========================================
- Coverage   68.76%   68.75%   -0.01%
==========================================
  Files         322      322
  Lines       16591    16589       -2
  Branches     4787     4786       -1
==========================================
- Hits        11408    11406       -2
  Misses       5151     5151
  Partials       32       32

Impacted Files
Coverage Δ

packages/expect/src/asymmetricMatchers.ts
83.33% <100.00%> (ø)

packages/expect/src/jestMatchersObject.ts
82.85% <100.00%> (-0.48%)
:arrow_down:

packages/expect/src/matchers.ts
97.86% <100.00%> (-0.01%)
:arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b9fc8ac...010797a. Read the comment docs.

source: gharchive/pull-request

authors: SimenB codecov-commenter

repo: facebook/jest

license: MIT

license_type: permissive

license_source: github-api


text:
Add missing yarn.lock for IT babel-plugin-jest-hoist

Summary
Missing from #3397, I suppose

Test plan
N/A

Codecov Report

Merging #3704 into master will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master    #3704   +/-   ##
=======================================
  Coverage   62.65%   62.65%
=======================================
  Files         183      183
  Lines        6707     6707
  Branches        6        6
=======================================
  Hits         4202     4202
  Misses       2502     2502
  Partials        3        3

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6986204...4de7faa. Read the comment docs.

authors: SimenB codecov-io


text:
adding back asynchronous.html content from documentation

Summary
The background  for this change is that the Asynchronous Testing documentation is showing "undefined".
This change reverts the documentation to before this change, so that the page content will be fixed.

Test plan
I simply reverted the code to the old page, which brings everything back to normal. The content is the same as the TestingAsyncCode.md document.

Since the bad commit in question was made by a bot, I imagine this indicates an underlying issue.

Thanks for looking into this, but I'm afraid this is not the right fix. The actual page is in the docs/ folder on master, and some change there must have broken rendering. You can run the website using "yarn && yarn start" in the "website" folder of this repo.

Hmm, that's strange. I tried looking in the docs/ folder on master they are all .md docs (presumably because docusaurus is being used.
Either way, it's working now so all is good. Jest-bot made the same changes I made (I used diffchecker to verify this).

Also, good point @jordansexton. Interesting that the commit was made by a bot.

authors: cpojer jordansexton shriyash


text:
Add reporter documentation to CLI docs

Summary
Update CLI docs to include --reporters CLI argument documentation (and limitations).
Test plan
Just a documentation update. No testing.

@SimenB @aaronabramov not sure if this was not documented for a reason. But here is documentation :)

Codecov Report

Merging #6605 into master will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master    #6605   +/-   ##
=======================================
  Coverage   63.73%   63.73%
=======================================
  Files         235      235
  Lines        8932     8932
  Branches        3        3
=======================================
  Hits         5693     5693
  Misses       3238     3238
  Partials        1        1

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9bb8909...7987116. Read the comment docs.


text:
Taint cannot flow into AsyncTask

I set the source and sink as shown in the code below, but Mariana-trench found 0, it looks like doInBackground is not in the flow.
Can Mariana-trench deal with scenarios where taint flowed into AsyncTask? Or how can i write config for this?
public void foo(Source source) {
    String txt = source.getText(); // Source here
    MyAsyncTask myTask = new MyAsyncTask(txt);
    myTask.execute(1000);
}

public class MyAsyncTask extends AsyncTask<Integer, Integer, Void> {

    private String txt;
    public MyAsyncTask(String txt)

    {
        super();
        this.txt = txt;
    }
    @Override
    protected Void doInBackground(Integer... params) {
        Intent intent = new Intent();
        intent.putExtra("txt",this.txt); // Sink here
        sendBroadcast(intent);
        return null;
    }
    @Override
    protected void onPreExecute() {
        Log.i("test","onPreExecute");
    }

}

Hi @wangzery,
Most likely, Mariana Trench doesn't have the source for AsyncTask.execute so it has no way to know that it calls doInBackground. Even if it had the code, I'm assuming it uses the system API to call it asynchronously, so Mariana Trench wouldn't see a direct call to it. That's why we are very likely to miss that flow.

source: gharchive/issue

authors: arthaud wangzery

repo: facebook/mariana-trench


text:
[NavigatorIOS] Navigator overlay NavigatorIOS bar

Is it possible for a Navigator component to overlay NavigatorIOS navigation bar? I can't make the modal transition of the JS navigator to overlay the native navigation bar.

This is an example of the issue. Looks confusing to open a modal an still have a navigation with a back button that does not close the modal.

I would try putting the NavigatorIOS component inside of the Navigator (it might not work because it takes extra work to set up UIViewControllers inside of arbitrary views but worth a shot).

yeah, you probably just don't want to mix these...but passing to Eric in case he's thought about this more.

Yeah, combining navigator with the native navigator is not very well supported. But I suspect it will work if you put the Navigator outside of NavigatorIOS

@alvaromb NavigatorIOS has a navigationBar and a view. When you nest Navigator inside it, it is being drawn into the view. Then NavigatorIOS draws the navigationBar on top of the view. Hence the view has no way to come on top of the navigationBar.
Please try the suggestion by @ericvicenti and share here!

Thank you for your replies. I'll try that as soon as I can @paramaggarwal, but I'm facing a tremendous amount of work right now and this has been removed from my top priority list. I expect I'll be able to try this on Friday.

I've switched from NavigatorIOS with a Navigator to display the modal to a full Navigator navigation.
However, if I set a navigationBar in the parent Navigator, it stays on top of the modal-Navigator.
This is the render code for the main Navigator:
return (
<Navigator
    navigationBar={
        <Navigator.NavigationBar
            style={styles.navBar}
            routeMapper={MnmNavigationBarRouteMapper}
        />
    }
    initialRoute={{
        title: this.state.selectedTab,
        component: MnmPublished,
        passProps: {section: this.state.selectedTab}
    }}
    renderScene={(route, nav) => {
        var props = route.passProps;
        props.navigator = nav;
        return React.createElement.bind(this)(
            route.component, props
        );
    }}
    configureScene={(route) => {
        if (route.sceneConfig) {
            return route.sceneConfig;
        }
        return Navigator.SceneConfigs.FloatFromRight;
    }}
/>
);

This is how I open another Navigator (the "modal" component):
this.props.navigator.push({
    index: 1,
    component: MnmCommentsContainer,
    sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
    passProps: {entryId: entrada.id}
});

And this is the code for the "modal" component:
render() {
    return (
        <Navigator
            renderScene={(route, navigator) => (
                <MnmComments entryId={this.props.entryId}/>
            )}
            initialRoute={{
                title: 'Comentarios'
            }}
            navigationBar={
                <Navigator.NavigationBar
                    routeMapper={MnmNavigationBarRouteMapper}
                    style={styles.navBar}
                />
            }
        />
    );
}

This last navigationBar is the one that has the red background. What I would like to achieve is  a stacked (right-to-left) navigation similar to the iOS native one and open a modal-like transition from one of the previously navigated views (something which I think is quite common in iOS app navigation). That modal should overlay the content that's behind. I would also like to prevent the right-to-left transition in the root navigationBar if possible.

Another thing that bugs me is that setting the content to flex: 1 with the custom navigationBar displays the content a couple of points behind the navigation bar, preventing the first element to be correctly displayed.

This is intentional. You should use content insets or top padding if you don't want that effect.

Thanks @ide! I've realised about that a while ago so I decided to close the issue :smile:

From this conversation I can't find solution
May be somebody will help
Here what I have

But I need Red one should overlay Green one NavBar

@ButuzGOL you can wrap your views in two <Navigator /> components. Take my pseudocode as an example:
<Navigator ref='topNavigator'
  render={() => {
    <Navigator ref='innerNavigator' render={ ... } />
  }}
/>

Then you use innerNavigator to make push-like transitions from right to left with a navigation bar. When you want to open your red modal and overlay the other views, use a Navigator.SceneConfigs.FloatFromBottom transition and make the push from topNavigator instead of innerNavigator.
Let me know if you have any trouble setting up this :smile:

@alvaromb thanks for comment
but I made it using http://facebook.github.io/react-native/docs/modal.html#content
So you can add there Navigator and it works like I expected

Cool @ButuzGOL! Modal it's a very nice component but keep in mind that if you render some kind of picker component there, chances are that you're not going to get it rendered because of this https://github.com/facebook/react-native/issues/2628 bug.

@alvaromb what if you set navigationBarHidden to true when you push your Navigator or modal schene for NavigatorIOS? would that work?

Haven't tried that @IlyasM, but honestly the nested <Navigator /> is the way to go.

authors: ButuzGOL IlyasM alvaromb ericvicenti ide paramaggarwal sahrens

repo: facebook/react-native