Maintaining UI Responsiveness
This is a bit of a rant on something that constantly annoys me about using my computer. It’s the lack of predictability regarding latency of simple operations.
Here’s an example: Click on the Start menu (assuming you’re running Windows). Did it appear instantly? Or did your computer spend 5 seconds digging around on the hard disk before drawing it? The answer is probably somewhere in between. Click it again, and it will appear instantly.
Many things are like this. An infamous one is the drives box in the standard Windows file dialog – clicking on that can easily take 10 seconds or so the first time, but after the first time, it’s cached, so it’s instant.
Funny thing is, some things really are (almost) always instant. Pressing Alt-Tab for example. It’s very rare that you have to wait for the system to draw the fast task switch window. Another thing that’s fast is Ctl-Alt-Del, which takes you to the Windows Security screen.
Here’s the thing: It frustrates users when something doesn’t work the same way every time. Computers are the only appliances that do this – when you press the Start button on the microwave and it instantly comes on. Press the Play button on a tape deck, and the tape starts playing.
Why?
Why are computers like this? There are two reasons. One is somewhat forgiveable: Stuff gets swapped out. If your computer has 256mb of memory, and you’re doing stuff that takes closer to 400mb of memory, then a bunch of what you’re working on is swapped out to disk, and when you try to switch back to it, it takes the computer a moment to get it all together. (I have an idea that might help with this, mentioned below).
The more common reason, however, is that in order to make it seem that our programs are starting quickly, we defer as much of the work as we can for as long as possible.
Delay loading DLLs for example – plugins are a perfect example of this. Some programs that support plugins defer populating the plugins menu until the user trips over the Plugins menu while looking for something, at which point the program has to do a lot of work loading up each DLL and interrogating it to see how to build the menu. Frustrating.
And, for most users today, unnecessary. I have a lot of RAM, I have CPU to spare. There’s no good reason that list of plugins shouldn’t be ready for me when I want it.
What to do about it
There are ways around most of these problems. I’m going to suggest two.
First, keep deferring long operations until after your program starts up users do like it when the app is ready to use quickly – but then after the main UI is up and the user can start working, start a low priority task to prepare the things you’ve deferred. Enumerate the fonts that are available. Load the plugins. Fill in the Favorites menu.
There are other things to keep in mind, of course. If the system is low on memory, then caching isn’t the way to go. Be aware of the state of the OS around you – but if the system is idle and there’s 400 meg of free memory, then why not initialize MSHTML in the background so that when the user wants to bring up a window that uses it, they don’t have to wait a few seconds for it to load up.
This is what the little tool that Microsoft Office installs to run at Startup does – it loads up a big chunk of Office, so that when you do want to run any of the Office suite components, it’s quick. Some folks think it’s cheating, but in the end it’s what the user sees that matters.
Priorities
The other thing you can do is raise your UI thread’s priority when appropriate. Windows itself tries to do this (give elevated priority to the app the user is interacting with), but it doesn’t seem to work very well.
Here’s an example. On my system, an Athlon XP 1700+, bringing up the Task Manager by pressing Ctrl-Alt-Esc happens almost instantly. But if I start a CPU hog (as simple as main(){while(1);}) it takes my system over 3 seconds to bring up the Task Manager.
There’s no excuse for this. When I press Ctrl-Shift-Esc, the OS knows I’ve just requested something, and the user is waiting for that operation to complete.
Microsoft Outlook fails horrible at this test. With my cpuhog.exe running, Microsoft Outlook 2003 takes over 5 seconds to switch between my Inbox and my Outbox. Normally, it’s instant, and with raised priority (using the Task Manager to set Outlook to AboveNormal) it’s instant.
Outlook knows the user just clicked on something and is waiting for the response. Getting a timely response to the user is more important than anything else the computer is doing at the time.
Anything that you’re doing where you know the user is waiting for something (like painting a window or responding to a button click by bringing up a dialog) and expects it to be instant deserves a higher priority than the WinZip operation or video compression or game going on in the background.
You have to be careful about this since if you hog the CPU while you have an elevated priority level, you’re going to severely hurt the rest of the system.. but careful application of elevated priority is a great way to improve the responsiveness of any application, especially on a busy system.
Locking things down
Something I want to experiment with is locking things down in memory. Boot the system up, click on the Start menu, open IE, look through the favorites list and history and a few other things, and then lock every committed memory page so that it can’t be swapped out. This should guarantee that the Start menu can always appear instantly. At least, I hope so.
January 9th, 2006 at 2:39 pm
Been thinking about the exact same thing. I’ve been thinking alot about how a possible scheduler should not use maxium “physical” cpu time as “full load”. Gimmi-everything-you-got apps should instead get cpu-max where maxiumum is the point where responsiveness starts to go downwards (on the responsiveness vs. proccess-cpu-time graph).
February 16th, 2006 at 2:21 pm
> Microsofot Outlook fails horrible at this test. With my cpuhog.exe running, Microsoft Outlook 2003 takes over 5 seconds to switch between my Inbox and my Outbox. Normally, it’s instant, and with raised priority (using the Task Manager to set Outlook to AboveNormal) it’s instant.
Have you tried this same action on a dual-core CPU?
I think you’ll be pleased with the results.
February 16th, 2006 at 4:13 pm
Yes actually – it’s one of the main reasons I like HyperThreading. It doesn’t actually make your system faster, but it seems to help a lot in these sorts of situations where one thread seems to be hogging something that’s keeping something else from being responsive.
April 3rd, 2007 at 8:37 am
Ctl-Alt-Del brings up “Windows Task Manager” in Windows XP, not the security screen you mention. What comes up depends on what Windows you have.
April 3rd, 2007 at 8:41 am
“This is what the little tool that Microsoft Office installs to run at Startup does – it loads up a big chunk of Office, so that when you do want to run any of the Office suite components, it’s quick. Some folks think it’s cheating…”
For more details on this, and whether or not it is CHEATING, read this short but excellent blog by Raymond Chen:
“Performance gains at the cost of other components”
http://blogs.msdn.com/oldnewthing/archive/2005/03/11/394249.aspx
April 3rd, 2007 at 8:30 pm
Ctrl-Alt-Del takes you to the security screen in every XP I’ve seen.. It’s a smaller dialog with a few buttons on it, one of which is Task Manager. Ctrl-Alt-Esc takes you right to the task manager.
June 26th, 2007 at 1:30 am
Actually it’s the Ctrl-Shift-Esc combo that will directly launch the task manager.
Great site
June 26th, 2007 at 7:11 am
Good point Drew, I fixed that in the article. Thanks.
October 17th, 2007 at 7:15 pm
Ctrl-Alt-Del will bring up the security screen in XP if it’s part of a domain, or if fast-user switching is disabled… otherwise it will bring up the task manager. So… you’re both right, sorta.