The advantage with WebSockets (over AJAX) is basically that there's less HTTP overhead. Once the connection has been established, all future message passing is over a socket rather than new HTTP request/response calls. So, you'd assume that WebSockets can send and receive much more messages per unit time. Turns out that that's true. But there's a very bitter reality once you add latency into the mix.
So, I created a simple app that uses SockJS and an app that uses jQuery AJAX to see how they would perform under stress. Code is here. All it does is basically, send a simple data structure to the server which echos it back. As soon as the response comes back, it starts over. Over and over till it's done X number of iterations.
Here's the output when I ran this on localhost
here on my laptop:
# /ajaxtest (localhost) start! Finished 10 iterations in 0.128 seconds meaning 78.125 messages/second start! Finished 100 iterations in 0.335 seconds meaning 298.507 messages/second start! Finished 1000 iterations in 2.934 seconds meaning 340.832 messages/second # /socktest (localhost) Finished 10 iterations in 0.071 seconds meaning 140.845 messages/second start! Finished 100 iterations in 0.071 seconds meaning 1408.451 messages/second start! Finished 1000 iterations in 0.466 seconds meaning 2145.923 messages/second
Wow! It's so fast that the rate doesn't even settle down. Back-of-an-envelope calculation tells me the WebSocket version is 5 times faster roughly. Again; wow!
Now reality kicks in! It's obviously unrealistic to test against localhost
because it doesn't take latency into account. I.e. it doesn't take into account the long distance the data has to travel from the client to the server.
So, I deployed this test application on my server in London, England and hit it from my Firefox here in California, USA. Same number of iterations and I ran it a number of times to make sure I don't get hit by sporadic hickups on the line. Here are the results:
# /ajaxtest (sockshootout.peterbe.com) start! Finished 10 iterations in 2.241 seconds meaning 4.462 messages/second start! Finished 100 iterations in 28.006 seconds meaning 3.571 messages/second start! Finished 1000 iterations in 263.785 seconds meaning 3.791 messages/second # /socktest (sockshootout.peterbe.com) start! Finished 10 iterations in 5.705 seconds meaning 1.752 messages/second start! Finished 100 iterations in 23.283 seconds meaning 4.295 messages/second start! Finished 1000 iterations in 227.728 seconds meaning 4.391 messages/second
Hmm... Not so cool. WebSockets are still slightly faster but the difference is negligable. WebSockets are roughly 10-20% faster than AJAX. With that small a difference I'm sure the benchmark is going to vastly effected by other factors that make it unfair for one or the the other such as quirks in my particular browser or the slightest hickup on the line.
What can we learn from this? Well, latency kills all the fun. Also, it means that you don't necessarily need to re-write your already working AJAX heavy app just to gain speed because even though it's ever so slightly faster, the switch from AJAX to WebSocket comes with other risks and challenges such as authentication cookies, having to deal with channel concurrency, load balancing on the server etc.
Before you say it, yes I'm aware than WebSocket web apps comes with other advantages such as being able to hold on to sockets and push data at will from the server. Those are juicy benefits but massive performance boosts ain't one.
Also, I bet that writing this means that peeps will come along and punch hole in my code and my argument. Something I welcome with open arms!