FAT's biggest weakness is file and directory fragmentation, an artifact of file allocation that causes files to be stored in several locations instead of one contiguous chunk. As a result, disk access to these fragmented files become slower than it should be. Modern filesystems do much better on the fragmentation problem, but they still suffer to some degree.
Fun Fact: The FAT filesystem pre-dates MS-DOS. It was created to manage files in Microsoft Disk Basic, and later, when Tim Patterson created 86-DOS, he used FAT as its filesystem. Later, Microsoft bought 86-DOS, and developed it into PC-DOS and MS-DOS (which are, of course, the same thing — PC-DOS is what it's called on IBM PCs, and MS-DOS on clones).
The fragmentation problem is especially apparent on disks that spend most of their time nearly full. As large files get squeezed into small spaces, further opportunities for fragmentation occur as these small fragments are later deleted and overwritten with other files. Pretty soon, you've got something that looks like this:
For those not familiar with Windows 2000's Disk Defragment utility, that's a graphical representation of the files on the disk. Unfragmented files are in blue, fragmented files are in red, and free space is white. There are also system files in green, but this particular disk (my WD 80GB USB hard drive) doesn't have any. You may also notice that there are fragmented files all the way at the end of the disk. I have filled this thing to the brim once, and yes, it resulted in hellish fragmentation.
So I hit the "Defragment" button, and a few hours later, it looks like this:
Muuuch better. Entirely contiguous, which is very good for the files already on my disk. Unfortunately, this defragmenter isn't very forward-looking. There are still holes there that a decent-sized file could trip over and get fragmented. For example, I copied a ~700MB movie to the drive and this happened:
That's less than optimal, let me tell you. Sitting from up here, it's obvious that what it should have done is put it at the large space at the end, but it doesn't seem like Windows' FAT implementation is that smart. For a comparison, to see if a third-party implementation might fare any better, I removed the file and did the same copy operation in Linux.
From the graph, it looks like Linux shuffled things around a bit, but it's probably just an artifact of Linux's allocation strategy coupled with the fact that this graph crams a lot of data in a very small space. Overall, Linux didn't fare any better, and from the look of it, might actually cause more fragmentation in the long run.
The Windows defragmenter provides no option for defragmenting free space, an option that would prevent this post-defrag fragmentation from happening. There doesn't seem to be a free defragmenter for Windows that can do that, and when I tried to find a FAT-specific defragmenter for Linux, the most common answer parrotted in forums is that you don't need one because (and I quote) "Linux doesn't get fragmented." You can't see it right now, but I am putting on my best "I can't believe society lets you reproduce" face in the direction of everyone who said that.
In reality, FAT gets so little play on Linux that nobody cares. There is a filesystem-agnostic defragmenter for Linux that I haven't personally tried. From what I've researched, the most common defragmentation method in Linux is "Copy all your files elsewhere, reformat the partition/drive, and copy all the files back," which is great, but not everyone has a hard drive's worth of space just lying around.
Oh, and a note to those of you about to defragment your FAT-formatted flash drives: don't. The extra wear and tear on the flash memory is not worth the speed savings. Furthermore, since flash has no moving parts, the speed savings will be minimal at best.
Now wasn't that fun and educational?