cypress
cypress copied to clipboard
Add HTTP/2 Support in Proxy Layer
The proxy layer currently doesn't really support HTTP/2. The only case in which a user can take advantage of HTTP/2 is if they are making a non-intercepted request through the https-proxy, and when #687 lands, all requests will be intercepted. When a request is intercepted, it can't be upgraded to HTTP/2.
Take this page, which loads 1000 images: https://flotwig.github.io/cypress-fetch-page/index1000.html
Loaded with HTTP/2, 1000 images load in 1362ms on my browser.
With HTTP/1.1, it takes 3896ms - three times as long.
Making our backend requests use HTTP/2 would give us a huge performance boost for making requests against servers that support it.
Obstacles:
requestlibrary doesn't support HTTP/2 - we'd need to fork or figure out a different way to try to upgrade tohttp2- need to figure out how HTTP/2 interacts with HTTP proxies
What are the smallest next steps possible to bring this ticket forward?
I found there's https://github.com/cypress-io/cypress/tree/develop/packages/https-proxy and in there is also a test suite. Are new tests to be added? I can see these new cases:
- [ ] HTTP/2 from the proxy to the target
- [ ] HTTP/2 from the browser to the proxy
- [ ] various conversions done in the proxy code
- [ ] target server is HTTP/1.1 only, but browser sent a HTTP/2 request
- [ ] target server is HTTP/2 and browser sent a HTTP/3 or 1.1 or QUIC request
@sesam There's two systems at play here, neither of which support HTTP/2 at this time:
- The HTTP/1.1 proxy server that all user requests go through - the server is stood up in
packages/server/lib/server.js, proxied requests are sent outgoing inpackages/proxy/lib/http/request-middleware.ts - The HTTP request library that is used to make outgoing requests for the proxy and for
cy.visit/cy.requestdoes not support HTTP/1.1 at all, neither doesrequest, the underlying library which it is based upon. Seepackages/server/lib/request.js
I think that, for real performance gains, both (1) and (2) would have to be updated to speak HTTP/2. This could be done in two separate PRs. After that's completed, an HTTP/2 conversation inside of Cypress would look like this (similar to how HTTPS connections are handled in Cypress currently):
- User attempts to load
example.cominside of the Cypress browser. - Browser makes a request to the Cypress proxy with the header line:
CONNECT example.com:443 HTTP/1.1 - Cypress routes this
CONNECTrequest to thehttps-proxy, which establishes an HTTP/2 server to handle requests toexample.com:443, and then pipes the incomingCONNECTrequest to this HTTP/2 server.- This is similar to how plain HTTPS is intercepted in Cypress today -
CONNECTrequests stand up an HTTPS server, which is then piped to the incomingCONNECTrequest.
- This is similar to how plain HTTPS is intercepted in Cypress today -
- Then, inside of
packages/server/lib/request.js, the outgoing HTTP request library is also updated to use HTTP/2. The requests/responses are proxied as normal viapackages/proxy/lib/http.
I haven't worked directly with HTTP/2 yet, but does this make sense? There are several different places where tests would need to be added, but it sounds like your ideas for test coverage would be a good start.
Some quick notes from messing with (1):
- Chrome supports HTTP/2 proxying using
--proxy-server=https://localhost:xxx. However, since Chrome doesn't support insecure HTTP/2, the proxy server needs to be listening on HTTPS. Which is fine. - Firefox does not seem to support HTTP/2 proxying.
I would like to mention that this is not only performance issue. All projects that use http2 streams they just can't use Cypress. Any updates on this issue ?
@midan888 nobody from Cypress is currently working on this issue.
Making our backend requests use HTTP/2 would give us a huge performance boost for making requests against servers that support it.
For completeness, this is virtually all servers not running on localhost in development mode, so this feature would help a huge number of usecases.
I use Cypress Ccomponent tests with Vite. Vite downloads huge amount of javascript modules separetly. Due to limitations of HTTP1 tests initial load is slow.
Waiting for 1.5s at each module to get 304 Not Modified response :/

I'm trying to test my Sveltekit app which use FaunaDB's document streaming to update the page in real-time. It works when tested manually with the dev server but not when tested in Cypress.
Are there any updates on this issue at this point?? My team is trying to use Cypress to test our app that is using grpc-web services and we are currently unable to intercept requests or even make successful requests currently from our app in a Cypress test.
Is there a way to entirely disable proxy?
This could be solved with https://github.com/cypress-io/cypress/issues/22319
As a workaround, I modified resources/app/packages/server/lib/browsers/chrome.js to exclude my http/2 requests since they use a different port in order to not break the streaming support: args.push('--proxy-bypass-list=<-loopback>;https://localhost:9000');
+1 :)
An update on this would be great to see. :) As it stands, projects using http/2 seem to have to look elsewhere.
+1 Multiple event sources make cypress useless
+1. I have a project with multiple EventSources connection. Currently we have to pending the automation scripts due to this issue.
As not to leave everyone hanging, this is been discussed recently internally (eg, "we need to make the network layer faster"), and not straight up ignored. I don't have a date for when this will be 1) worked on or 2) completed right now, though.
Once there is more information, this issue will be updated. I hope we can do it soon, fast is good, faster is better.
This is causing a lot of slowness in a new application that uses lots of chunks by default (default for a lot of new apps), so glad to see this is being worked on
@bigcakes what version of Cypress are you on? There were some incremental (not major) tweaks to things during Cypress 11, maybe some of those help?
I agree that apps making many requests (especially if you use Vite for your dev server and test against it, too) it can be a major bottleneck.
@lmiller1990 We are on 11.2, but I am loading about 100 javascript chunks + css/images + API calls currently so the http1 limitation is fairly impactful to our initial load speed
Agreed, it's slow with many chunks, some of the slowness was addressed in this PR https://github.com/cypress-io/cypress/pull/25209 which was released in Cypress 12.3.0, if you can update to 12.3.0, that might help, it helped my app using Vite load much quicker in Cypress. Another user reported the same, see here: https://github.com/cypress-io/cypress/issues/22868#issuecomment-1383633338 (this thread has a ton of info about the exact problem you are encountering).
That actual HTTP/2 improvements will be the biggest help, this is getting worked on but I am not sure on ETA.
Perf is definitely better since 12.3.0, thank you to all contributors for that. However, it is still noticeably slower, especially in the vite use case.
HTTP2 seems like a win-win direction, but id also note the convo on https://github.com/cypress-io/cypress/issues/25201.
@lmiller1990 I did update us and saw ~20% test speed increase, however definitely looking forward to http2
Actually, I've changed my mind on this. HTTP2 might not be the core issue at hand in many scenarios. See https://github.com/cypress-io/cypress/issues/25201#issuecomment-1438475302
+1
+1
+1 have same issues!
Just wondering whats happening regarding support got http2 - my current project has switched to http2, now all tests are broken and getting pressured to use another framework that supports it.
Hi @markbeaman44 - your app should work fine, even if you are using HTTP/2 - if you've got a minimal reproduction, I'd recommend creating a new issue and we can take a look.
This issue in relating to how Cypress internally handles requests - the idea is to use HTTP/2 for performance reasons. Apps using HTTP/2 work fine right now, they might just load bit slower when running in Cypress.
If you have an actual issue where an app using HTTP/2 is not working at all in Cypress, please share a minimal reproduction in a new issue and we can take a look. Thanks.
@lmiller1990 it doesn't work if you use a lot of streaming connections due to the lack of multiplexing with http/1.1. Originally I was able to work around it because our application used a separate port for the streaming connections (grpc). I bypassed the proxy for the streaming connections. But now we consolidated to a single port, so all of my tests are broken also.
Right, I see, I think this makes sense. If you can post a minimal reproduction, that would be really useful -- ideally in a separate issue.
Having more "my app cannot be tested in Cypress" like use cases will greatly help with prioritizing this feature. Right now, the main reason to do this is to make Cypress faster -- performance is always good to have, but a real business use case (eg - "I want to use Cypress, but I can't) certainly helps the product team when they re-evaluate the priority on issues every other month or so. Thank you!