Written by John Reed
CSS media queries make it possible to serve up mobile-optimized images to reduce your load times across various devices. But what about when you rely on a third-party API or CDN to get your images? We recently cut image load times by 88% by utilizing Flickr and open-source libraries. Here’s how we did it.
The Problem
One of our clients uses Flickr to manage photos for their ExpressionEngine website, allowing them to upload high-resolution images automatically resized into various formats. They simply add the photoset ID to a custom EE field, and we, in turn, pull those photosets via the Flickr API to produce custom slideshows. However, the high-resolution images that look amazing on a desktop display took forever to load on mobile devices when not on a Wi-Fi network. So we needed a way to detect the end-users device.
Enter Open-Source
Device sniffing doesn’t have to be a frightening endeavor.
Mobile Detect is a lightweight PHP class for detecting a wide array of mobile devices wrapped up in a nice open-source package. Combined with Phlickr (another PHP library for simplifying Flickr API calls), we have all the tools we need to make our optimizations.
The Solution
First, we retrieve our photoset from Flickr using the
getPhotos method, requesting the ‘original_format’ extra to use on super-wide displays.
<?php require_once 'Phlickr/Api.php'; $Phlickr = new Phlickr_Api( FLICKR_API_KEY, FLICRK_API_SECRET ); $photos = $Phlickr->executeMethod( 'flickr.photosets.getPhotos', array( 'photoset_id' => 'FLICKR_PHOTOSET_ID', 'extras' => 'original_format' ) ); ?>
Now that we have our photoset from Flickr, we can implement our mobile detection to display the appropriate size for each device we’re targeting. The getPhotos response doesn’t format the image URLs, but this is helpful as it allows us to build our URL using the
size suffix best suited to the device we’re on.
<?php require_once 'Mobile_Detect.php'; $detect = new Mobile_Detect; // iterate through $photos retrieved above foreach( $photos->xml->photoset->photo as $photo ) { // store XML node attributes $farm = (string) $photo->attributes()->farm; $server = (string) $photo->attributes()->server; $id = (string) $photo->attributes()->id; $secret = (string) $photo->attributes()->secret; $o = (string) $photo->attributes()->originalsecret; $format = (string) $photo->attributes()->originalformat; // base URL for all photos $src = 'https://farm' . $farm . '.staticflickr.com/' . $server . '/' . $id . '_'; // use default for iPhone (500px on longest side) if( $detect->isIphone() ) $src .= $secret . '.jpg'; // use 'b' suffix for tablets (1024px on longest side) elseif( $detect->isTablet() ) $src .= $secret . '_b.jpg'; // use original image else $src .= $o . '_o.' . $format; // echo the image echo '<img src="' . $src . '" alt="">'; } ?>
Before implementing the mobile detection library, we defaulted to the original image. For this particular client, these images were, on average, in the neighborhood of 500K. After adding mobile detection, we delivered images with an average size of 60K to handheld devices, an 88% reduction.