back to low-priority prefetch operations, seems to work better (voodoo?)
PDImage caches isHidden and isDeleted dictionary lookup

These properties are used extensively, e.g. when rebuilding the list of
visible images. The dictionary lookups were showing up at the top of
the sample during app-launch.
use a per-instance-spinlock to synchronize image layer image update

Was using the CATransaction lock, but was seeing some contention. This
appears to make scrolling a bit less flickery.
defer starting view controller progress spinner for .25s
work-around CA locking issues when updating thumbnails

from the code that loads the unscaled proxy image:

  FIXME: but for thumbnails I'm running into a problem with updating
  CALayer contents from multiple threads.

  What's supposed to happen is CA's prepare_commit() does the expensive
  image conversion before taking the transaction lock, allowing other
  threads to continue unimpeded. But it appears that sometimes the
  conversion is happening in commit_layer(), while the lock is held.
  This is probably because the same layer tree is being modified from
  multiple threads, even though each layer isn't and the commits are
  interfering (I thought we'd made the contents property fully isolated
  in 10.9, but perhaps not..?)

  So the workaround for that is to skip this stage and go straight to
  the scaled proxy for thumbnail layers, so that the image has been
  decompressed and color matched by the time the layer sees it. But
  only if the prefetching has already completed -- we don't ever want
  to scale the full-size image down to thumbnail size. This will also
  look better than e.g. GL_LINEAR_MIPMAP_LINEAR.
image layer no longer needs trilinear filtering for thumbnails