Performance should always be tested rather than theorized... having said that, I'll make a quick point to show why I believe that Websockets are both more performant and more reliable:
The advantages of websockets over polling are two:
Before Http/2, each new polling request required a new connection. Websockets would save you the resources related to the new connection.
Obviously, when using Http/2 this is no longer the case, as Http/2 is designed to leverage the same connection. Moving on to advantage number 2:
Each new polling request is a request and requires all the resources related to the request (such as polling the database to review changes etc').
Websockets would save you the resources related to polling requests, as data will be pushed only when available, minimizing the number of interim requests.
In fact, websockets still save you a lot of resources related to the actual polling. Most websocket updates (if not all) use data update hooks, so that no polling is involved (push is initiated right after the update, without a need to poll and review for changes).
Even when polling is used for websocket data, there is only a single polling event for all the clients, vs. a polling event for each client.
What about Http/2 Push?
This should put to rest the question of performance... but,
one might inquire - "what about Http/2 push? doesn't it mean websockets are no longer necessary?"
This is somewhat debatable and you can find discussions about it (for example, here).
As you can see from my answer to the linked question, I believe that the websocket are more reliable, and here's why:
some of the info here isn't in the original answer and other info from my original answer was skipped or summarized
As stated by the Http/2 draft (standard by now?):
An intermediary can receive pushes from the server and choose not to forward them on to the client...
This is also true for the browsers (if you look into the "settings" frames documentation). For instance, while I was playing around with Iodine's Http/2 server (I'm the author), I noticed that Safari was setting push notifications to "off"... I'm not sure if this is still the case, but it's a big deal for me when I think websockets vs. Http/2.
Also, Http/2 connections can be terminated by the client (or the server or anyone in between) while the browser is still visiting the page, effectively disabling Http/2 push notifications.
When this happens in websockets, the onclose
callback can be used to re-establish a connection. With Http/2 there's nothing you can currently do.
For these reasons (and a few others), I believe that Websockets allow for both better performance and better reliability.
EDIT (relating to comments)
SSE (Server Sent Events)
Allow me to state why I believe that websockets are superior to SSE.
SSE is a development based on long-polling, pre-websockets era.
It could have been great for server to client messages, except for a few things:
It's server-side implementation mostly sucks.
As far as Http/2 goes, I hadn't seen any implementations, so I can't comment on what might happen, but:
Many SSE implementations will open a new thread for each connection or implement a second IO reactor running along side the server's IO reactor, just for managing the SSE connections.
This will waste resources when compared to websockets (although I saw some websocket implementations doing the same - brrr...).
SSE is uni-directional and cannot be used for client to server sent messages.
This means you still use Http+AJAX for data sent from the client to the server.
Unlike Websockets, both SSE and Http+AJAX are stateless, so you need to go through authentication for every new message cycle, decoding the Http/2 headers, encoding the Http/2 headers and using all the resources related to a fresh request...
Websockets allow you to skip all that by being stateful. This means that Http headers and authentication are performed only once when the connection is opened and all the messages are sent within this persistent context that lasts for the lifetime of the connection.
SSE isn't as well supported by the community.
It's harder to find good libraries or information pertaining to SSE when compared to Websockets... Even though SSE pre-dates websockets!
I think this is a good proof for webwebsocket's superiority in actual production.
Websocket tunneling within Http/2
I believe this concept and idea to be a mistake and that tunneling shouldn't be used.
I think there's a reason that the suggestion from February 14, 2014 wasn't renewed after it expired on August 18, 2014 (to the best of my knowledge).
Here are a few reasons I can think of:
Websockets and Http/2 are designed to have different lifetimes and connection timeouts.
While Http/2 are long lived when compared to Http/1.1, the browser (or server) might disconnect them at any time (with or without implementing a websocket disconnection pattern).
Routers, proxies and load-balancers relate to Http/2 to set their timeout settings for the connection. It is unlikely that the same settings will apply to the timeout settings used today for websockets.
Websockets and Http/2 are designed for different clients.
Http/2 is designed for Http clients - primarily browsers.
Websockets, on the other hand, are designed for all web clients to help navigate through intermediaries such a ISPs, Firewalls, Proxies, NAT routers etc'. (i.e., this package)
This means that when you decide to write a native application and use your web-server as a back-end, that native application should use websockets for better connectivity (it's connectivity statistics are better than raw TCP/IP).
Your native application doesn't speak Http/2, but it does have the stripped down Http/1 needed to establish a websockets connection.
If you decide to use tunneling, you probably wouldn't be able to leverage your current code for a native application.