GUI Programming: Always perform network requests asynchronously
Why does one feel ones so much more in control, when using Firefox, than Internet Explorer?
When you select a slow link in Internet Explorer, the whole program hangs for about 1-2 seconds. Firefox doesn't. Although 1-2 seconds is hardly a large % of ones life, it makes a big difference to the experience one has when using Firefox.
Recently I wrote something similar to an IM client (written in Java). It sits on the Windows tray. You can log in, and open a window where you can do various things. The data stored on a website (communication over XML-RPC).
MSN Messenger has one tray-icon for the user being logged out, a different one for the user being logged in, and amazingly (I thought), a third one for during the time the program spends communicating with the servers to log the user on.
In my system, log on is just one single XML-RPC call, with all the necessary data returned in the response. This was a design goal, to never have more than one client-server request to represent a particular user action.
The back-end to this XML-RPC call is a simple perl script which uses a few objects to represent things such as Users. These objects are simple enough, they just make a few SELECTs against our super-fast database. So I thought, as any request to our back-end takes say max 0.2 seconds, I needn't make that asynchronous to the UI of the Java program. And I certainly don't need a separate icon to display during that time!
If I'd ever stated that decision out loud, I would have heard myself saying it, and realized what a nonsense that is.
- While it may only take 0.2 seconds on the server, there's latency to consider, i.e. the time for the packets to flow from the client to the server and back again.
- One can't take into account how slow the user's network connection might be.
- There may well be more than one request from client to server, multiplying the latency. Just because there is one XML-RPC request doesn't mean there are no other requests going on underneath, for example DNS lookup of the hostname to connect to.
- If there is a queue of HTTP requests in Apache, waiting for the FCGI to answer the XML-RPC request, then the time the HTTP request to wait in the queue will also be added to the duration of the call perceived by the user.
- What if there is a server-problem, and all requests take 2 seconds? A design not tolerant of things going wrong is a bad design.
- Even 0.2 seconds is noticeable in a front-end.
- Programming asynchronously in Java is not difficult. So it need not be avoided.
So now, every time I log on using that program, the dialog to log in opens, one clicks connect, and ... wait ... until the success or failure response is shown. And in that time, the program is just dead. It doesn't even redraw its windows. It may only be 0.5 seconds, but you notice it.