Create a separate SpriteFrameLoader for caching sprite frames.

Only a few classes used the LoadAllFrames method, and they all use it with a transient cache. By moving the LoadAllFrames method into a new class, we can skip the now redundant frame cache in SpriteLoader, saving on memory significantly since the frame data array can be reclaimed by the GC. This saves ~58 MiB on frames and ~4 MiB on the caching dictionary in simple tests.
Minor style nit: It may be a good idea to rename these variables to `frameLoader` to make it clear that they aren't regular SpriteLoaders.