5 ms·
> The latency is the same because modern browsers multiplex HTTP requests over a single TCP connection that is left open. In my experience this isn’t true; fi
by clappski 1mo ago
> The latency is the same because modern browsers multiplex HTTP requests over a single TCP connection that is left open.
In my experience this isn’t true; firstly you’re relying on an implementation detail of the platform that you’re executing on, of which you have no control over on the client side. Secondly, even if you aren’t opening a new connection per request, you’re still travelling through an entire HTTP stack implementation rather than the incredibly simple WebSocket protocol - effectively a length and a mask to get the contents, rather than some (in http1 land) fuzzy parser.
If you can guarantee you’re hitting http2 or http3 then you might be closer in latency, but due to the complexity of both I would imagine plain http1 negotiated persistent WebSockets provide the best latency.
- jallmann 1mo agoSure, but SSE connections in the browser - the typical use case - are persistent, so there shouldn't be frequent re-connecting. Unlike WebSockets, browser SSE also has a built-in recovery mechanism so you don't miss events across reconnects (`Last-Event-ID` header), although this does require explicit support from the server-side app. Given that the WebSocket handshake has an additional round-trip, SSE would typically be faster in terms of time-to-first-byte. > you’re still travelling through an entire HTTP stack implementation rather than the incredibly simple WebSocket protocol Both protocols have their own minimal framing, but "an entire HTTP stack" is a stretch. It's hard to argue that `data:value\n\n` is more complex than the WebSocket binary protocol. Simplistic, sure (no binary payloads), but also simple enough to, say, pipe through a regex. Good luck doing that with WebSocket.
- crabmusket 1mo ago> faster in terms of time-to-first-byte Yes, but all these approaches are optimised for long sessions, not TTFB. If that were very important (say, ecommerce) you might prefer a framework that can hydrate and send the full page on first request, rather than setting up a socket to get data. > data:value\n\n I believe the poster was referring to requests from the client to the server having to traverse the HTTP stack, not data coming down from the server via the SSE stream.
- jallmann 1mo ago> I believe the poster was referring to requests from the client to the server having to traverse the HTTP stack, not data coming down from the server via the SSE stream. Ah that's probably correct, I mis-read.
- galaxyLogic 1mo agoBut, if you can do things on the client (with JavaScript) you don't need to send (so many) requests to the server, making latency less of an issue. Doing things on the client means user's CPU is doing some work which else would need to be done on the server, for maybe thousands of clients at the same time. So I understand some people don't like JavaScript, but then I think the solution would be WebAssembly. I mean the point of distributed computting is that the computational load can be distributed. Perhaps counter-intuitively that often also means less need fo communications and latencies.
- clappski 1mo agoIn my experience (building things like realtime trade monitoring front ends), client side processing sucks. You have 10 or 20 data sources that need joining up in a client defined set of ways (think viewing X price feed with Y trade feed and some Z meta data feed), all natively sending many updates a second - I’ve tried and failed to build a client side heavy implementation (although that might just be my lack of front end skills!), much better to have some DAG of backend processing units that the front end can consume feeds from and remain really light, just managing subscriptions and rendering the data.
- galaxyLogic 1mo agoDeveloping on the back-end has much more mature tools in my experience, IDEs and QA tools. Client-development is often not much fun dealing with the browser dev-tools. So I share your feeling thath serious development is better done on the back-end. But in principle there should be a client-dev-tool as good as those for the back-end. There is some progress. I've used WebStorm to do client-side work which has a niocve feature that as I debug my client-side program I can use WebStorm instead of browseer-tools and if I see a typo in my code while debugging it I can edit it away and it gets saved into the source-file where it came from.
- paulddraper 1mo agoWebSockets have head-of-line blocking. HTTP/2 does not.
- zero_shift 1mo agoBut surely it does? It is TCP, even with multiplexing I thought that was the whole motivation for building HTTP/3 on QUIC (UDP)?
- paulddraper 1mo agoWell, yes. There is always some form of it on TCP. But your HTTP/2 reverse proxy won't block fast responses on slow responses. As long as your WebSocket reverse proxy does the same, you're fine. (And same stipulation for your client.)
- treve 1mo agoYes you are right. With HTTP/2 responses can be sent out of order, but once they are sent down the pipe they have head of line blocking and have to arrive at that order, unlike QUIC. Websockets don't really have an advantage here because typically websockets are implemented server-side as event based systems, and if a RPC paradigm is put on top of it has the same properties as HTTP/2 request/responses ordering. So if HTTP/2 doesn't have head of line blocking, then you can't argue that websockets do.
- 7bit 1mo agoh2 does have head-of-line blocking on the transport level.
- est 1mo ago> incredibly simple WebSocket protocol Srsly bro? Websocket is simple? Talking about handling state persistency and connection partitions, such a headache.
- clappski 1mo agoYes, WebSockets are very simple to implement a server or a client for. It’s a small variable size header, 5 or so frame types and a typically constant mask over the contents.
- Borg3 1mo agoHehe, yeah.. I recently touched WebSockets and yes, its complicated stuff. But hey, for vibe coders everything is easy, right? ;)
- clappski 1mo agoYou can genuinely implement the protocol with good performance in 150/200 lines, from memory; 1. Read the opcode 2. If PING, send PONG. If binary or text, continue 3. Read the header size 4. Read the payload size (which is a variable-width integer, hence getting the header size first) 5. Unmask the payload 6. If fin in the header is false, add the payload to a buffer. Else, either immediately dispatch (continuation buffer is empty) or buffer and dispatch (continuation buffer isn’t empty) There are extensions like setting RSV1 to indicate you need to decompress the payload, but that’s the only one I’ve encountered building clients for >20 WebSocket based APIs.
- Borg3 1mo agoDamn, im must be very bad then: 210 lines @ src/webirc.rb Skeletal test, just to move data from/into websocket. Nothing more... Anyway, yes, doable. But compared to HTTP1/1 request or just TCP socket, way more complicated. That was unexpected.
- clappski 1mo agoI’ve had more difficulty building http1.1 implementations that broadly work, still a lot of weird stuff like incorrect chucked message parsing you have to handle on the server side. Yeah plain TCP is obviously simpler but you can’t consume a raw socket in a browser, that’s why web sockets win for me - easy to consume over api and browser.
- rcarmo 1mo agoThis seems misguided since the whole point of the browser stack is not reinventing the wheel. The heinous crimes to code maintainability that have been perpetrated on top of websockets litter the halls of technical debt, haunted by the liminal career ghosts of too clever coders…
- clappski 1mo agoThe claim I was rebutting was specifically about latency. Of course you can make a mess of it, no different than you can with request/response based protocols. On the other hand, you are going to struggle to implement bidirectional event based protocols without WebSockets that can be consumed by browser based clients or an application - WebSockets are very useful for that exact case, where you have a mixed client type consuming. It means you don’t need to offer web hooks and rest and some streaming protocol, you just have a WebSocket with some defined JSON message types without the rigmarole of distributing .proto or whatever.