cypress-io/cypress

Experimental feature: disableProxy

csvan opened this issue · 27 comments

csvan commented

What would you like?

This has been raised in the past, but the original author gave up on it (and Cypress, unfortunately). Closed (but not resolved) issue is here for context: #22319 (comment)

This feature would add the experimental option to completely disable the Cypress proxy and let the running browser (and Cypress) speak directly to the network.

Why is this needed?

As explained in the docs, Cypress uses a proxy for, among other things, modifying code which potentially would break Cypress during runtime. However, the docs also acknowledge that not all sites are affected by such code, and even provides an option (modifyObstructiveCode) which partially disables it. The proxy is also used for several other features.

However, the proxy also incurs several notable penalties:

  • No HTTP2/3 support (see especially #3708 for implications)
  • Only supports gzip compression (see #6197)
  • Unpredictable network behavior (outgoing headers modified etc)
  • Most importantly - demonstrably severe performance impact, especially for modern web apps which use chunking extensively.

So while the proxy certainly has important uses, there should be an option to disable it completely if a team determines they have no use for the extra functionality and would like to optimise performance instead.

Other

While I advocate for Cypress personally at my workplace, I am seeing rising pressure from colleagues to consider Playwright instead - primarily due to performance reasons. The author of the original issue ended up doing the same.

I love Cypress approach to testing, but I can only acknowledge that performance is - and has been for years - one of the primary weaknesses of the framework. The team has done impressive work over the last releases (especially in 9 and 10) to address many sticking points, but much more needs to be done in order to level the playing field with competing solutions - especially Playwright. I believe this would be a step in the right direction.

There is an in-flight PR to address a regression in the network proxy that may mitigate some of the performance concerns noted here: #25209

I am also curious about this. My understanding is Cypress cannot function without some sort of network proxy. Not only do many features depend on it, but I (think) there's some fundamental requirement for some sort of network proxy (could be mistaken, but the concept of a network proxy has been in Cypress since the very early days, far before things like cy.intercept existed.

Whether we can make some of the features opt-in or opt-out would be another discussion.

Before doing this, since the goal is to go faster, there's a better alternative - updating our network stack to some more modern libraries, and using HTTP/2, which is up to 10x faster. I think this would help greatly with performance.

There is an issue tracking that here: #3708.

I want to be able to do this, possibly with the ability to say which URLs are proxied and which are not.

If you try and run E2E tests locally against an application in dev mode that uses an unbundled dev tool like Vite, you have thousands of requests for static files. It takes about 20 seconds to load the app instead of < 0.5 seconds without cypress in play.

csvan commented

@lmiller1990 my understanding (and I am not too familiar with Cypress internals) is that the proxy is primarily necessary for:

  1. Removing obstructive code (frame-busting etc)
  2. Providing a layer for network stubbing and other forms of request-analytics

I am not sure either of the above are strictly necessary, and again not all projects need either of them. It would be helpful to know if there is anything in the proxy without Cypress cannot function altogether. Our projects have no intrusive code, for example, and we do not use any of the network features at all apart from visit and request.

It would be helpful to know if there is anything in the proxy without Cypress cannot function altogether

This is what I am trying to find out. I'm sure there is something around how Cypress injects itself - whether we can decouple that and have some option to make the proxy do less and thus improve performance is another question.

@adam-thomas-privitar I think that's actually a bug that is fixed by #25209. You can test this out right now by installing the pre-release with that patch: 6b78454#comments. If you do try it, let me know if it helps. I also want to use Vite and I want to go fast.

Edit you tried it, thanks! I still think we can go faster, but if you see anything that seems like it's unusually slow, it's probably a bug - you should create an issue.

csvan commented

Awesome, many thanks for your efforts @lmiller1990 <3

Cypress will always need to work as a proxy in order to function correctly - however the performance problems you mentioned are absolutely critical for us to implement/fix. As @lmiller1990 and others have mentioned, we have already fixed a few known issues, but specifically HTTP/2 support is on our radar.

I'm not aware of how chunked responses could be impacted performance wise outside of HTTP/2 support. If that's something you could provide more clarity/examples of, we could take a look at it. There are an significant number of things we do under the hood in order to be performant... chunking for instance is definitely a main concern of ours.

/cc @flotwig