Lazy Finder
Tuesday, January 19th, 2010This is an expansion of a reply I wrote to a tweet by Daniel Jalkut. He wrote:
Imagine if the iPhone home screen showed a matrix of "generic" icons before filling in real ones. Mac Finder is a disgrace.
He's referring to behavior introduced in Snow Leopard: When you visit a folder for the first time in a session, the Finder shows every symbolic link and alias with the kUnknownFSObject icon (
), every application with the generic application icon, every file with the generic document icon, and every folder with the generic folder icon, before displaying the item's real icon and then its Quick Look thumbnail.
Compare the environment of SpringBoard (on a non-jailbroken device) to that of Finder:
| iPhone | Mac OS X |
|---|---|
|
Every item is of one kind: Application. |
Items are of any of three kinds: File, folder, and bundle. The Finder must handle each kind differently. |
|
Everything is on one iPhone's worth of flash memory. |
Files may be distributed over any number of volumes, local and remote; however, the general case is all files on one hard disk, which is the startup disk. |
|
Because the iPhone doesn't allow background processes, it's the only app running, with only a few built-in, light-on-file-system-access exceptions (the heaviest of which is probably Mail). |
Any number of applications may be running, and they may be accessing files on the same volume you're browsing. |
|
Accessing any file in flash memory is as quick as accessing any other file (random access). |
Disks are not so predictable: Accessing one file and then another can incur milliseconds of seek time. Doing this repeatedly for dozens or hundreds of files (possibly in multiple Finder windows at different scroll positions) may cause the disk to thrash. You can hope that the OS can put the requests into a favorable order, but you can't rely on it, and there's only so much it can do. |
|
Flash memory is always active. |
Most users aren't using flash memory. Hard disks may be spun down to conserve power. If this is the case, the disk will need to be spun up, which can take seconds. |
|
All files (that is, all applications) are local. |
Some volumes may be on remote machines, across a local network or the internet; depending on throughput and latency, every access to such a volume can take tenths of a second. |
|
All applications are in one place, making caching of icons or their filenames easy. |
Applications aren't the only user-visible bundles, and any bundle can be anywhere. |
Compare also how SpringBoard and Finder obtain icons*:
| iPhone | Mac OS X |
|---|---|
|
Assuming that the icons themselves aren't cached:
|
(All of this may happen inside NSWorkspace and/or Icon Services.)
|
SpringBoard hasn't much to do, it's in a straightforward environment, and the task and environment provide a couple of obvious caching strategies. The iPhone doesn't have as much processing power, but what it has is enough—it can just get and display the icon without being lazy about it.
In fact, SpringBoard probably doesn't even need to be asynchronous about it; all it needs to do is keep three pages of icons (current, next, and previous) in short-term memory. When the user flips one page, drop the farthest page out of the short-term memory cache and load the next one into it.
Meanwhile, on the Mac, getting an icon is not straightforward, and the environment can throw a monkey wrench into the works at any point. Every icon can take dozens, hundreds, or thousands of milliseconds to display, and more icons mean more opportunities for a stall. The solution is to load and show the icons asynchronously and in parallel—but then, what to show in the meantime?
Thus, for the Finder, lazy loading makes sense. The Finder can show you what it has (filenames and other basic metadata) immediately. You can work with those files, scroll to other files, or move through the folder hierarchy without having to wait for icons. And while you do that, the Finder has all the time it needs to asynchronously fetch the icons and, if it's still appropriate, display them.
It's a feature, not a bug.





