One of my favorite quotes is from Walter Isaacson’s biography on Steve Jobs.
“If it could save a person’s life, would you find a way to shave ten seconds off the boot time?” he asked. Kenyon allowed that he probably could. Jobs went to a whiteboard and showed that if there were five million people using the Mac, and it took ten seconds extra to turn it on every day, that added up to three hundred million or so hours per year that people would save, which was the equivalent of at least one hundred lifetimes saved per year.”
Isn’t that wonderful to think about? Only a bit of effort can save so much time. This is a philosophy I apply to everything I do. From trying to save seconds from typing to decreasing load speeds on my projects, I try to make things as quick and fast-moving as possible. Speed and performance are features.
I used this mindset when developing my photo website by employing different methods. Even though five million people aren’t visiting my site, it’s important to me that the site provides the best experience possible.
It’s taken me a long time before reaching anywhere near these speeds. I’ve been developing this site for about five years now, and it started out with a score of about 30. So, how did I improve its performance by so much?
WebP Image Format
WebP is an image format by Google supported on all modern browsers. Its load speeds are crazy fast and compression sizes crazy small, with minimal loss of quality. Whenever possible, I load WebP images.
The first place any user will see pictures is thumbnails. Here, it is easy for me to display either WebP or JPG - I use the
<picture> tag. It allows me to give different image sources and identify a fallback
<img> tag in case none work. This supports all browsers without me having to do manual detection.
This makes my life easy, as I simply render each thumbnail with a
<picture> tag and put in the corresponding paths to the WebP and JPG version.
The second place I show the images is if the user clicks on a thumbnail to view the photo. Adding WebP support for this feature was tricky. The gallery library I use, Magnific Popup, allows clicking of the thumbnail by wrapping it in an
<a> tag. This means that the
href for that tag can only be a single path to one of the images.
So by default, I keep all the paths to the JPGs. But in the background, I use a library called Modernizr to detect if the browser supports WebP. If it does, then I iterate over these links and set the image source to the WebP file. The only drawback is if the user opens one quickly, then it’s possible that a user may expand the full JPG image. However, I’ve never found this to occur when testing.
Another feature that I’ve leveraged to decrease loading time is responsive images. The idea of this is to serve the smallest possible image needed based on screen size and display density. I only use this for thumbnails, as the way I render expanded images is too restrictive. In addition, the preloading gallery works well enough such that a user should only have to wait for a single image to load. Especially if it’s WebP, this is not an issue.
For the responsive thumbnails, I support 4 different sizes: 400px, 600px, 800px, and 1024px. The browser then decides which to serve. This saves time by loading smaller images when possible, also using less data (important for a site with many photos). To do this, I again take advantage of the
<picture> tag and the different
<source>s inside of them.
This is a lot of code for rendering a single image, so I wrote a bash script to generate all file types and different sizes for all images in a specific directory. It converts all expanded size images into WebP, and all thumbnails into 3 more sizes of both WebP and JPG.