Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests that iterate over many DOM elements with .each() run slower in Electron during cypress run in 3.8.0 #5987

Closed
juan-fernandez opened this issue Dec 17, 2019 · 28 comments
Labels
type: performance 🏃‍♀️ Performance related type: regression A bug that didn't appear until a specific Cy version release v3.8.0 🐛 Issue present since 3.8.0

Comments

@juan-fernandez
Copy link

juan-fernandez commented Dec 17, 2019

Current behavior:

We have a storybook cypress smoke test that opens all the stories and checks that they render. The test itself is very simple:

it('can load all components', () => {
    cy.get('[id^=explorer]').each($component => {
      cy.wrap($component)
        .click()
        .get(`[id^=${$component[0].id}--]`)
        .each($story => {
          cy.wrap($story)
            .click()
            .wait(50)
            .componentHasLoaded()
        })
    })
  })

With

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then($iframe => {
    const doc = $iframe.contents()
    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

Our test duration went from roughly 2 minutes to roughly 8 minutes as seen in the graph:
Screenshot 2019-12-17 at 16 15 11
(after some commits we decided to roll back to cypress@3.7.0)

There were absolutely no changes in the app code.

The only change was moving from cypress@3.7.0 to cypress@3.8.0. From what we've seen, there are no noticeable changes in the test (no new logs or errors) other than the interaction just being slower. The command to run cypress is exactly the same but we've noticed that the Electron version has changed from 73 to 78 as seen in the screenshots:
Screenshot 2019-12-17 at 16 20 54
Screenshot 2019-12-17 at 16 21 11

Desired behavior:

We'd like to know if there is something to do on our end to go back to the old speed or if there is a bug in cypress that created this performance regression.

Steps to reproduce: (app code and test code)

Run a storybook test with:

it('can load all components', () => {
    cy.get('[id^=explorer]').each($component => {
      cy.wrap($component)
        .click()
        .get(`[id^=${$component[0].id}--]`)
        .each($story => {
          cy.wrap($story)
            .click()
            .wait(50)
            .componentHasLoaded()
        })
    })
  })

With

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then($iframe => {
    const doc = $iframe.contents()
    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

Versions

cypress@3.8.0

Performance regression found in

Build-agent version 1.0.22569-ba1c5aa5 (2019-12-16T14:39:46+0000)
Docker Engine Version: 18.09.6
Kernel Version: Linux b9cc89c6eb3c 4.15.0-1052-aws #54-Ubuntu SMP Tue Oct 1 15:43:26 UTC 2019 x86_64 Linux
Starting container cypress/base:12.6.0
  image cache not found on this host, downloading cypress/base:12.6.0

Also locally in MacOS 10.15.2

@jennifer-shehane
Copy link
Member

Definitely roll back to 3.7.0 for now.

Can you run the tests with --browser chrome and verify if the slow performance also happens when run outside of Electron?

This example is a bit complicated since it requires loading Storybook. Can you provide a simpler example or a storybook url to visit that we can run the tests against?

@jennifer-shehane jennifer-shehane added stage: needs information Not enough info to reproduce the issue type: performance 🏃‍♀️ Performance related v3.8.0 🐛 Issue present since 3.8.0 labels Dec 18, 2019
@juan-fernandez
Copy link
Author

juan-fernandez commented Dec 18, 2019

Thanks for your fast response! 😄

Sure, we've setup a one-off domain for this specific purpose:
https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1

We've used the same button over and over to have roughly the same number of stories we ourselves are testing. I think this is relevant because the test seems to slow down as it advances.

These are the different results using that endpoint:

  • cypress@3.7.0 with Electron 73 (headless) (2 minutes):
============================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:    3.7.0                                                                              │
  │ Browser:    Electron 73 (headless)                                                             │
  │ Specs:      1 found (storybook/storybook.spec.js)                                              │
  │ Searched:   cypress/integration/storybook/**.spec.js                                           │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  storybook/storybook.spec.js                                                     (1 of 1)


  storybook
    ✓ can load all components (120237ms)


  1 passing (2m) 
  • cypress@3.8.0 with Electron 78 (headless) (10 minutes):
====================================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:    3.8.0                                                                              │
  │ Browser:    Electron 78 (headless)                                                             │
  │ Specs:      1 found (storybook/storybook.spec.js)                                              │
  │ Searched:   cypress/integration/storybook/**.spec.js                                           │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  storybook/storybook.spec.js                                                     (1 of 1)


  storybook
    ✓ can load all components (624573ms)


  1 passing (10m)
  • cypress@3.8.0 with Chrome 79 (headless) (11 minutes):
====================================================================================================

  (Run Starting)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Cypress:    3.8.0                                                                              │
  │ Browser:    Chrome 79 (headless)                                                               │
  │ Specs:      1 found (storybook/storybook.spec.js)                                              │
  │ Searched:   cypress/integration/storybook/**.spec.js                                           │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


────────────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  storybook/storybook.spec.js                                                     (1 of 1)


  storybook
    ✓ can load all components (681227ms)


  1 passing (11m)

The test code is above. Let me know if you have any trouble reproducing and thanks again for your help!

@fr0
Copy link

fr0 commented Dec 20, 2019

This is a serious issue for me as well.

@jennifer-shehane
Copy link
Member

@juan-fernandez Can you update this test so that it runs to completion as you've described? I'm not familiar with storybook or what this test is even supposed to do exactly.

Test code I'm running.

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then($iframe => {
    const doc = $iframe.contents()
    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

it('can load all components', () => {
  cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')
  cy.get('[id^=explorer]').each($component => {
    cy.wrap($component)
      .click()
      .get(`[id^=${$component[0].id}--]`)
      .each($story => {
        cy.wrap($story)
          .click()
          .wait(50)
          .componentHasLoaded()
      })
  })
})

Result:

Screen Shot 2019-12-23 at 2 11 42 PM

@juan-fernandez
Copy link
Author

@juan-fernandez Can you update this test so that it runs to completion as you've described? I'm not familiar with storybook or what this test is even supposed to do exactly.

Test code I'm running.

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then($iframe => {
    const doc = $iframe.contents()
    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

it('can load all components', () => {
  cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')
  cy.get('[id^=explorer]').each($component => {
    cy.wrap($component)
      .click()
      .get(`[id^=${$component[0].id}--]`)
      .each($story => {
        cy.wrap($story)
          .click()
          .wait(50)
          .componentHasLoaded()
      })
  })
})

Result:

Screen Shot 2019-12-23 at 2 11 42 PM

@jennifer-shehane Thanks for your reply and attempt to reproduce!

I think I know what is happening. Try do add this:

cy.visit('?path=/settings/shortcuts').wait(3000)

and run with baseUrl:

CYPRESS_baseUrl=https://unruffled-lalande-8277bd.netlify.com cypress open

You can directly visit https://unruffled-lalande-8277bd.netlify.com?path=/settings/shortcuts too but you do need to wait.

This can be seen in https://www.loom.com/share/06105d01e4c445b183e466be6042d8d6

@sainthkh
Copy link
Contributor

sainthkh commented Dec 24, 2019

Hello, I've been researching this issue on Ubuntu and want to share what I've found out.

TL;DR; It might be because of the too much memory usage.

Start with the given situation

The first test I did was this:

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then(($iframe) => {
    const doc = $iframe.contents()

    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

describe('issue #5987', () => {
  it('test', () => {
    cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')
    cy.get('#explorerbutton-0').click()
    cy.get('[id^=explorer]').each(($component) => {
      cy.wrap($component)
      .click()
      .get(`[id^=${$component[0].id}--]`)
      .each(($story) => {
        cy.wrap($story)
        .click()
        .wait(50)
        .componentHasLoaded()
      })
    })
  })
})

Compared to @jennifer-shehane's code, I've added cy.get('#explorerbutton-0').click() in the middle, because when Cypress visited https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1, the button-0 element is open by default. And cy.wrap($component).click() closes the first element and it causes the problem above.

Anyway, the test starts to slow down after button-30 and it becomes really slow after button-40. In my case (Ubuntu 18.04 with hardware info below), there was not much change between 3.7.0 and 3.8.0.

Screenshot from 2019-12-24 18-23-31

They both cannot finish 100 buttons. (I've even watched a 30+ min gaming YouTube video while running test with my smartphone but the test didn't end.) The times to end 50 items were 1128 in 3.8.0 and 1076 in 3.7.0.

Break down the test into small tests and run them separately.

To understand why this happened, I tested with the code below:

describe('issue #5987', () => {
  let list = []

  for (let i = 0; i < 100; i++) {
    list.push(i)
  }

  before(() => {
    cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')
    cy.get('#explorerbutton-0').click()
  })

  let list2 = [0, 1, 2, 3, 4]

  list2.forEach((j) => {
    list.forEach((i) => {
      it(`test ${100 * j + i}`, () => {
        cy.get(`#explorerbutton-${i}`).then(($component) => {
          cy.wrap($component)
          .click()
          .get(`[id^=explorerbutton-${i}--]`)
          .each(($story) => {
            cy.wrap($story)
            .click()
            .wait(50)
            .componentHasLoaded()
          })
        })
      })
    })

    it('close all', () => {
      list.forEach((i) => {
        cy.get(`#explorerbutton-${i}`).click()
      })
    })
  })
})

It tests 100 buttons for 5 times. As you can see, the test is the same. But it uses the different test method. It calls it() function 500 times.

In this case, this 500 tests ended under 600 seconds. (I remember it was 567 or something.) There was little slowdowns sometimes, but in most cases, it was fast enough.

(If you're not stress testing Cypress, it might be the best workaround for now.)

After these 2 tests, I wanted to check if it happens because there are too many commands in a test. (Around button-40, there were about 800 items in the list.)

Create a simple test to reproduce the slowdown.

So, I created the test 3.

describe('issue #5987', () => {
  it('test', () => {
    cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')

    for (let i = 0; i < 2000; i++) {
      cy.get('#explorerbutton-0').click()
    }
  })
})

It's really simple. It just clicks button-0 2000 times. Like your test case, it started fast but slowed down after about 1000 items in the list.

To understand why it happens, I examined chrome with top command. And I found out when chrome uses about 5% (about 1.6GB) of RAM, it starts to slow down significantly, because max memory per tab is about 1.4~1.8GB according to this Stack Overflow answer.

What's next?

To check the hypothesis that it is caused by "too much memory usage", can you check how much memory is used in 3.7.0 and 3.8.0?

If this hypothesis is right, what I need to check next is:

  • What made this memory usage different?
  • What is using memory a lot like this?

@jennifer-shehane
Copy link
Member

@sainthkh Yes, we've experience this ourselves in our docs tests - performing a large amount of commands in a single test slows Cypress down. (It is why we skip these tests when run in interactiveMode https://github.com/cypress-io/cypress-documentation/blob/develop/cypress/integration/table_of_contents.js#L29:L29)

Have you tried reducing the numTestsKeptInMemory to 0 to see if this has any effect.

I am most interesting in a possible regression, although the performance is an overall issue to be addressed. If we introduced something recently, it will be much easier to fix.

@sainthkh
Copy link
Contributor

@jennifer-shehane numTestsKeptInMemory doesn't make much difference. It might be because it is for tests, not commands. In this example, we need to create about 2000 commands.

And it seems that 1.6GB of memory isn't enough for them.

I might need to check:

  • if this doesn't happen in early versions on Ubuntu. Unlike Mac, this problem currently happens on 3.7.0 and 3.8.0 on Ubuntu.
  • After that, I might need to check MobX. I'm suspecting MobX observers using too much memory. (I might be wrong.)

After experiments are done, I'll share the result with you.

@jennifer-shehane
Copy link
Member

@sainthkh Yeah, I believe that is the case. I thought we had an issue open for this somewhere but I can't find it.

@sainthkh
Copy link
Contributor

sainthkh commented Jan 2, 2020

Experiment Result:

  • This slowdown happens on 3.0.0. The difference is that it starts around 50th item. It's about 10-20 items later to 3.8.1.
  • It seems that MobX isn't the major problem. I created a list of 2000 items with MobX like reporter did. It worked and it only used about 1.1%(0.35GB) of memory.
  • I found something interesting. If the tested website is simple, it doesn't consume the memory that much.

For example,

describe('issue #5987', () => {
  it('test', () => {
    cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')

    for (let i = 0; i < 1000; i++) {
      cy.get('#explorerbutton-0').click()
    }
  })
})

The test above slows down after about 1000 entries. It uses 5%(1.6GB) of memory.

<!--issue-5987.html-->
<!doctype html>
<html lang="en">
<body>
  <button id="btn">Button</button>
</body>
</html>
describe('issue #5987', () => {
  it('test', () => {
    cy.visit('/fixtures/issue-5987.html')

    for (let i = 0; i < 1000; i++) {
      cy.get('#btn').click()
    }
  })
})

But when we change the tested html site simple, it works. It passed over 2000 commands, but used only 2%(0.64GB) of memory.

We need to find out why simple site structure makes this difference.

@sainthkh
Copy link
Contributor

sainthkh commented Jan 7, 2020

I realized that I was investigating a wrong problem. In packages/driver tests, isInteractive is always true. So, snapshots are always taken. That's why I couldn't reproduce the problem.

When I created a new project and started fresh, I could reproduce it. There was a real difference between runtime.

  • 3.7.0: 123733ms
  • develop branch: 675211ms

I was tracking which commit caused the problem and found out that it is slowed down after #5849 (upgrading Electron to 7.1.4).

In Electron 5.x, the memory use increased fast (about 0.3GB/min, i.e. 0.6GB in 2 minutes). But after Electron 6.x, it doesn't increase fast. It just went to 0.6GB after 10 minutes.

Newer electron causes some kind of thrashing because it doesn't increase memory use fast.

To fix this problem, I used js-flags, max_old_space_size=4096, max_semi_space_size=2048, etc. on environment.coffee file. But nothing worked.

From Electron 5.x to 6.x, these are changed:

  • Chromium: 73 -> 76
  • Node: 12.0.0 -> 12.4.0
  • V8: 7.3 -> 7.6

It seems that something related to memory allocation has been changed.

@jennifer-shehane
Copy link
Member

@sainthkh We just merged in an Electron 7.1.7 upgrade. May be worth seeing if it's been resolved in there. I've messaged the team about your theory.

@sainthkh
Copy link
Contributor

sainthkh commented Jan 9, 2020

@jennifer-shehane Unfortunately, it didn't change, it took 11 min 25 seconds.

@jennifer-shehane
Copy link
Member

@sainthkh Which spec are you running exactly when you are running the experiments to show the performance difference?

@juan-fernandez
Copy link
Author

could this have anything to do with https://support.google.com/chrome/thread/23003371 ? The test does keep scrolling to get the next story

@sainthkh
Copy link
Contributor

@jennifer-shehane

Cypress.Commands.add('componentHasLoaded', () => {
  cy.get('#storybook-preview-iframe').then(($iframe) => {
    const doc = $iframe.contents()

    cy.wrap(doc.find('#root')).should('not.be.empty')
  })
})

describe('issue #5987', () => {
  it('test', () => {
    cy.visit('https://unruffled-lalande-8277bd.netlify.com/?path=/story/button-0--default-1')
    cy.get('#explorerbutton-0', { timeout: 30000 }).click()
    cy.get('[id^=explorer]').each(($component) => {
      cy.wrap($component)
      .click()
      .get(`[id^=${$component[0].id}--]`)
      .each(($story) => {
        cy.wrap($story)
        .click()
        .wait(50)
        .componentHasLoaded()
      })
    })
  })
})

I added { timeout: 30000 } to avoid test failure because it took long to rendering storybook.

@jennifer-shehane
Copy link
Member

There is a performance issue introduced in Chrome 79 described here: #6023 (comment)

Just wanted to link that issue here in case anyone does find their issue isolated completely to Chrome 79, it may be that issue.

@fr0
Copy link

fr0 commented Feb 3, 2020

I used the Chrome dev tools Performance tab to profile one of my tests running under 3.7.0 vs 3.8.3. There is a definite difference in the code path.

3.7.0:

Screen Shot 2020-02-03 at 2 14 44 PM

Screen Shot 2020-02-03 at 2 15 49 PM

3.8.3

Screen Shot 2020-02-03 at 2 19 33 PM

Screen Shot 2020-02-03 at 2 20 05 PM

It seems that 3.8.0 might've introduced some change in the isVisible check? The root cause of the extra slowness in this particular timing is layout thrashing due to forced reflow.

Screen Shot 2020-02-03 at 2 25 42 PM

Based on what I'm seeing in this trace, I am guessing that the culprit is #6000 or #5916, but I haven't done a bisect.

@marmite22
Copy link

marmite22 commented Feb 7, 2020

Hi,

The following test takes about 25 seconds on 3.7.0 and about 1:30 on 3.8.3.

I wonder if the issue is something to do with cy.get(...).each()?

describe('CAN LOOP', () => {
    it('SHOULD LOOP', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

    });
});

If I simplify the loops in the test to

describe('CAN LOOP', () => {
    it('SHOULD LOOP', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
        cy.get('.toc li a').each(($a) => {
            cy.wrap($a).click();
        });

        cy.get('.toc li a').each(($a) => {
            cy.wrap($a).click();
        });

        cy.get('.toc li a').each(($a) => {
            cy.wrap($a).click();
        });
    });

});

Then is takes ~15seconds on 3.7.0 and ~23seconds on 3.8.3

@marmite22
Copy link

marmite22 commented Feb 12, 2020

In version 3.8.3 Test 1 takes SIGNIFICANTLY longer than Test 2 (note the only difference is the placement of the cy.visit()). In 3.7.0. both take almost exactly the same amount of time.

Test 1

describe('CAN LOOP', () => {

    it('SHOULD LOOP', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });
    });
});

Test 2

describe('CAN LOOP', () => {
    it('SHOULD VIST', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
    });

    it('SHOULD LOOP', () => {

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });
    });
});

@marmite22
Copy link

This has the needs more info tag. Is there anything I can do to help besides the above tests that show the issue?

@cypress-bot cypress-bot bot added stage: needs investigating Someone from Cypress needs to look at this and removed stage: needs information Not enough info to reproduce the issue labels Feb 18, 2020
@san-slysz
Copy link

Not sure if linked, but I have this (#6597) in both 3.8 and v4.

@vjau
Copy link

vjau commented Feb 29, 2020

I have the same problem. In my case it's limited to Electron. Version 4 is the same

Running times : 
3.7.0
------ 
Chrome 80
1st run 95.31
2nd run 94.98

Electron 73
1st run 49.4
2nd 60.06
3rd 50.93

3.8.X
------


Chrome 80
1st run 103.15
2nd run 101
3rd run 102.98

Electron 78
1st run 110.90
2nd run 355.23
3nd run doesn't complete


@peruukki
Copy link

I ran Git bisect with the simplified test case in #5987 (comment), measuring how long it takes to run. I got the same culprit as in #5987 (comment): the test run slows down from 18 seconds to 30 seconds starting from commit 3403713 Electron upgrade (#5849). Indeed, I didn't notice any significant difference between the Cypress versions when running in Chrome.

Here's how I bisected in case it's useful:

git bisect start v3.8.0 v3.7.0 --
git bisect run ./test.sh

test.sh content:

#!/bin/bash

# Source: https://stackoverflow.com/a/49412454/305436
function float_gt() {
  perl -e "{if($1>$2){print 1} else {print 0}}"
}

COMMAND="yarn dev --run-project my-tests --spec '**/tests/loop.js'"
DURATION_LIMIT=30

yarn

# Source: https://stackoverflow.com/a/26785328/305436
exec 3>&1 4>&2
DURATION=$(TIMEFORMAT='%R'; { time $COMMAND 1>&3 2>&4; } 2>&1)

if [ $? -ne 0 ]; then
  echo "Test run failed, skipping commit"
  exit 125
fi
exec 3>&- 4>&-

if [ $(float_gt $DURATION $DURATION_LIMIT) == 1 ]; then
  echo "Took too long: $DURATION"
  exit 1
fi

echo "Fast enough: $DURATION"

@juan-fernandez juan-fernandez changed the title Migration To Cypress 3.8.0 Slowed Test By 4x Migration to Cypress 3.8.0 Slowed Test by 4x Jun 28, 2020
@jennifer-shehane jennifer-shehane added the type: regression A bug that didn't appear until a specific Cy version release label Jul 9, 2020
@amar2lyb

This comment has been minimized.

@marmite22
Copy link

In version 3.8.3 Test 1 takes SIGNIFICANTLY longer than Test 2 (note the only difference is the placement of the cy.visit()). In 3.7.0. both take almost exactly the same amount of time.

Test 1

describe('CAN LOOP', () => {

    it('SHOULD LOOP', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });
    });
});

Test 2

describe('CAN LOOP', () => {
    it('SHOULD VIST', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
    });

    it('SHOULD LOOP', () => {

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });
    });
});

I have just tested and can confirm that Test 1 is still significantly slower than Test 2 on Cypress 5.2.0

@jennifer-shehane jennifer-shehane changed the title Migration to Cypress 3.8.0 Slowed Test by 4x Tests that iterate over many DOM elements with .each() run slower in Electron in 3.8.0 Sep 29, 2020
@jennifer-shehane jennifer-shehane changed the title Tests that iterate over many DOM elements with .each() run slower in Electron in 3.8.0 Tests that iterate over many DOM elements with .each() run slower in Electron during cypress run in 3.8.0 Sep 29, 2020
@jennifer-shehane
Copy link
Member

Concerning the first example in #5987 (comment) I can recreate the behavior of the specs running slowing in headless Electron in 3.8.0.

Repro

describe('CAN LOOP', () => {
    it('SHOULD LOOP', () => {
        cy.visit('https://en.wikipedia.org/wiki/Star_Trek');
        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });

        cy.get('.toc li').each(($el) => {
            cy.wrap($el).find('a').each(($a) => {
                cy.wrap($a).click();
            });
        });
    });
});

Timings

cypress run Electron headless or headed:

  • 3.7.0: 25 secs
  • 3.8.0: 92 secs
  • 5.3.0: 108 secs

cypress open Electron:

  • 3.7.0: 175.25 secs
  • 3.8.0: 115.6 secs
  • 5.3.0: 141.61 secs

cypress open Chrome:

  • 3.7.0: 92.72 secs
  • 3.8.0: 92.21 secs
  • 5.3.0: 111.88 secs

@BlueWinds
Copy link
Contributor

BlueWinds commented Oct 25, 2022

Just doing some cleanup as we begin looking into this internally; closing in favor of #4164, which contains links to a bunch of different examples (including this one).

Definitely a real issue, and closing doesn't mean we're not paying attention; just consolidating a bit as we start looking into this more seriously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: performance 🏃‍♀️ Performance related type: regression A bug that didn't appear until a specific Cy version release v3.8.0 🐛 Issue present since 3.8.0
Projects
None yet
Development

No branches or pull requests

10 participants