One of the challenges of running any sort of website where your users upload images is you and your users interests are very different. Your user has no understanding of performance, does not care about the tradeoff between image quality and page load time, and has no real concept of what file types they should use. Instead of trying to train your users, I’ve implemented some easy best practices to keep your pages performant when you’re displaying images outside of your control. There are lots of more intensive practices you can implement, but these will be your easy wins.
- Enforce using PNGs and JPEGs only. These will end up getting cached by both the browser and intermediaries, other image types won’t. They also have the broadest support for compression software
- Automatically Compress Images on Upload. There’s tons of automated, command line compression tools you can use that will compress the image as its being uploaded. I use Paperclip Optimizer with Paperclip to handle this. I also use Sprockets Compressor to do this for my assets. I’ve heard great things about JPEGMini but haven’t personally tried it.
- Add Cache-Control Headers. You NEED to have cache control headers on your images. I assume you’re hosting all of your assets on a CDN or S3, so make sure you go ahead and set a year-long cache on all of them as long as you don’t anticipate your images changing. If you can, force yours to delete and re-upload instead of replacing an image. It’s the same amount of work, just enforces unique URLs for your images. If you’re using Rails, the Asset Pipeline already creates a digest for your compiled assets so this is never a problem for them.
- Use a CDN. Amazon Cloudfront, Akamai, Rackspace Cloud Files-all will host your files and cache them at edge nodes. Instead of serving your files from your server or a single datacenter, your images will be a lot closer to your users, meaning much quicker download times.
There’s lot more things you can do such as only downloading the size images you need instead of resizing one large image, using WebP when you have a browser that supports it, using a low quality image on initial DOM rendering and replacing it with the higher-quality image after load, and lots more advanced techniques to try as your website grows and your performance requirements change.