Browser Dialer: Change from ES5 to ES6+ for performance#3832
Browser Dialer: Change from ES5 to ES6+ for performance#3832
Conversation
|
I agree with everything you are saying. The mixed style is mostly because of historical reasons and because nobody here really knows idiomatic JS (is my guess...). With regard to the redesign, I think that if it makes the JS code simpler, it's a win. I think the golang code will probably become more complicated, but you can try it. It would be particularly good to get rid of the JS loop in the GET codepath, as it is the source of some kind of resource leak. The PR works on my machine, so I'll merge it now. Thanks for the PR, looking forward to the next one! |
可以改一下, |
这是否意味着 browser dialer 可以支持 HTTPUpgrade 了? |
No, it cannot. Since |
First of all... What. The. Heck.
Problems with the current code
I can only do so much to try getting the current code up to shape.
A mix of ES5 and ES6+ syntax in compatible mode
I really don't know if the browser dialer was designed to work on Internet Explorer, but proper web stream API support don't really exist on that platform. So why didn't the browser dialer have strict mode enabled when this could bring performance gains...
Unscoped value declarations with
varTL;DR, avoid using
varat all costs.varintroduces problems of the yesteryear, whereletdeclarations are much safer, cleaner and straightforward, with stricter constraints allowing the JS JIT to work more efficiently.Uses
if-elsechains instead ofswitchI don't know why
if-elsechains are used instead ofswitch, as this isn't either C or C++. Both JS and Go support using switch on any type, and JS in specific has single-pass optimizations forswitchstatements, avoiding sequentially querying for each possibility.Fundamental design flaws
The problems
I have no idea why the data plane and the control plane are smashed together. Evident in the code that each message of the single local WebSocket connection is parsed, where with a separation of data plane and control plane can avoid most of the processing. Unless it's tuned for the individual upload packets SplitHTTP needs, so in this specific case data could be smashed together. Since WebSocket can overwhelm the browser easily with enough throughput and without any counteracting measure, the only solution for now would be get rid processing as much as possible on the data plane.
And somehow the browser dialer of SplitHTTP is implemented via WebSocket instead of
fetchrequest in either direction. At least on Chrome,ReadableStreamcould be set as the body, so instead of reading and processing chunks, bodies can simply be passed along without the browser doing much at all. Even better, since Chrome has streaming support for WebSocket in the latest versions, a zero-cost optimization is incredibly feasible with separated control and data planes.A probably better design
Feel free to conduct critique on this, as this isn't fleshed out much yet.
/control?token=csrfTokenControl socket. Where the control messages should go, be it
WS,GETorPOST. Though non-streamed uploads should go here as well to reduce the overhead./ws?socket=aRandomIdDirect WebSocket message pass-through between the server and the client.
/http?socket=aRandomId&role=ingressWhere the magic for streamed web request happens. Allows stream pass-through without any manual reading, unless it's on Firefox.
Because the browser doesn't support
h2c, two request streams for each client-facing streamed SplitHTTP connection are required.ingressstreams are what the Xray server sends to the client, andegressstreams are what the client sends to the server.