2

I am building a web application in Node.js, and using Socket.IO to handle data transfer between my client and server sides.

The core piece of my web application is a content feed. My client-side Javascript emits a Socket.IO call for the contents of the newsfeed. Once the response comes back from the server, it populates the feed on the webpage using JQuery.

My issue is that Socket.IO doesn't cause the browser's page loading indicator (for Chrome, this is a spinning wheel in the webpage's tab) to show. I want it to show. Without this loading indicator, my webpage looks like it's finished loading when it really hasn't (the feed hasn't been populated yet).

What is the proper solution to this problem? Thank you in advance!

ryzh
  • 263
  • 1
  • 3
  • 11
  • Can you provide your client side code for socket.io in question ? – hiteshtr Feb 07 '14 at 07:16
  • It's just this: socket.emit("getRequests", this.info);. That's it. My issue is not that the socket code doesn't work. It's that the browser's page-loading indicator (the spinning wheel) doesn't appear while the front-end is waiting for its response. – ryzh Feb 07 '14 at 07:23
  • The proper solution is to use custom spinnig wheel. For example put an animated gif on your page and show it when you do `.emit` and hide it when you receive the data. That's for example how FaceBook works. When you click on a menu item a small spinnig wheel appears next to it. – freakish Feb 07 '14 at 07:30
  • @freakish is saying right or you can refer to this question: [link])http://stackoverflow.com/questions/9314730/display-browser-loading-indicator-like-when-a-postback-occurs-on-ajax-calls), by using iframe you can emulate the loading – hiteshtr Feb 07 '14 at 07:34
  • 1
    Thank you so much for the responses! Yes, I have considered putting the custom spinning wheel - it just feels a bit hacky to me. Is there really not another standard solution? I imagine this must be a problem for a lot of Socket.IO developers... – ryzh Feb 07 '14 at 07:40

1 Answers1

2

There is no proper answer per se: browser vendors have different rationales for why certain activities would and would not show "loading" states: A good rundown here.

In general, ajax-like requests (things asynchronous to actual full page loads) should probably NOT show loading indicators by default, as busy states indicate to users that the browser is slow/busy, and we use ajax requests for all sorts of background tasks. There are, of course, times when a developer would want to show these indicators (form submission, single page apps that download subsequent pages via ajax: times when we want to convey to the user that something major is happening and that they SHOULD wait for it to complete) but we don't have a lot of control over forcing that to happen when it comes to async requests. The only real way to "fake" it on some browsers is to load content in an iframe: some modern browsers do trigger the "busy" state in that case.

With Websockets, most vendors have, probably quite reasonably, applied the same logic as ajax requests: there are a lot of operations you'd want to do with websockets that can happen without a user actually initiating them directly, so they shouldn't trigger that "browser is seriously busy, hold on a second" feel. And, like with ajax, there's sadly no api I know of for countermanding that design decision.

The iframe solution is limited: it works in some browsers but not all (notably, it's ignored in all major mobile browsers). And doing it crudely (i.e. creating a hidden iframe for when you want it to trigger the load indicators and removing it when you want to cancel them) has costs: you basically need to hit a resource that is designed to "stall" (like a php page that just runs sleep(10000) and so keeps the connection open). That's both weighty (extra http request just to trigger an effect) and also ties up some server with keeping open connections that are essentially not doing anything. That probably won't scale, particularly if that server is the same one hosting your app.

You're probably instead stuck with coding a custom loading indicator (spinner, fake progress bar fixed at the top of the screen). It's not satisfying, but it's the only thing guaranteed to communicate some of what you want to users. I have a solution for jQuery's ajax that exploits the iframe approach (Noisy JSON) that you could potentially reproduce as a plugin for socket.io, but if you're using websockets, that basically means falling back to ajax-style communication for requests. And you're still out of luck on Safari, mobile, and newer IEs.

Dtipson
  • 1,564
  • 16
  • 21