Improve page speed in WordPress with srcset

Published March 12, 2019
.* :☆゚

If you are serving a lot of images on a page, it is important to think about how you’re serving them. You want the images to look good on large screens, but don’t want to be loading in these humungous sizes for smaller screens and mobiles, where size matters less.

If you’re developing themes with WordPress, I’d like to point you to a pretty neat solution that is handled out of the box, and something you can implement fairly easily.

Simply use the wp_get_attachment_image_srcset() function for all your image requirements. Yes, even backgrounds (hello object-fit, bye IE 11)

The great thing about this function is that you can take advantage of WordPress’ amazing image mangement to serve appropriately sized images depending on the browser size, and control resized images with ease from the settings/functions.php.


The old + clunky way

You may have displayed a feature image like this:

<?php
if ( has_post_thumbnail() ) :
$thumb_id = get_post_thumbnail_id();
$thumb_url_array = wp_get_attachment_image_src($thumb_id, 'large', true);
$thumb_url = $thumb_url_array[0];
$title = get_post($thumb_id)->post_title;
$alt = get_post_meta($thumb_id, '_wp_attachment_image_alt')[0]; ?>

<img src="<?php echo esc_url($thumb_url)?>" alt="<?php esc_attr_e($alt); ?>" title="<?php esc_attr_e($title); ?>">

<?php endif;

or with ACF, like this:

<?php
$image = get_field('feature');
$size = 'large';
$thumb = $image['sizes'][$size];
$title = $image['title'];
$alt = $image['alt'] ? $image['alt'] : $title;
?>

<img src="<?php echo esc_url($thumb); ?>" alt="<?php esc_attr_e($alt); ?>">

Notice these functions generate an image tag with just one image.


The newer, more user-friendly way

Use the srcset function! FOR EVERYTHING 😁

<?php
$id = get_post_thumbnail_id();
$size = 'medium';
$img_src = wp_get_attachment_image_url( $id, $size );
$img_srcset = wp_get_attachment_image_srcset( $id, $size );
$title = get_post($id)->post_title;
$alt = (get_post_meta($id, '_wp_attachment_image_alt')[0]) ? get_post_meta($id, '_wp_attachment_image_alt')[0] : $title;
?>
<img src="<?php echo esc_url( $img_src ); ?>"
srcset="<?php echo esc_url( $img_srcset ); ?>"
sizes="(min-width: 768px) 500px, 100vw"
alt="<?php esc_attr_e($alt); ?>"
title="<?php esc_attr_e($title); ?>"
class="featured-image">

I personally use this particular function this way so I have more control over how each of the image’s attributes are printed.

The real advantage of using srcset in WordPress is the ability to simply rely on WordPress’ fantastic image processing to generate smaller sizes, and serve them up automatically.

The only thing you need to provide this snippet is the image attachment ID. The snippet will then retrieve both the $img_src and the $img_srcset using the wp_get_attachment_image_url() and wp_get_attachment_image_srcset() functions. Notice how the image tag now has a sizes attribute? That’s where you put all your media queries depending on how you want the image to resize.

In my example, I’m asking it to display all images above 768px screen width to display at 500px wide. If the browser size is less than 768px, it will display this image at 100vw.

You can of course define more queries if you so desire:

sizes="(max-width: 320px) 350px,
        (max-width: 768px) 500px,
        (max-width: 1200px) 800px,
        100vw"

Using srcset in WordPress makes uses of it’s generated image thumbnails. The default thumbnail sizes are:

<?php 
the_post_thumbnail('thumbnail');       // Thumbnail (default 150px x 150px max)
the_post_thumbnail('medium');          // Medium resolution (default 300px x 300px max)
the_post_thumbnail('medium_large');    // Medium Large resolution (default 768px x 0px max)
the_post_thumbnail('large');           // Large resolution (default 1024px x 1024px max)
the_post_thumbnail('full');            // Original image resolution (unmodified)

Wordpress’ preset image thumbnails have gone the extra mile for me in literally all my web projects- I’ve never had to set custom thumbnail sizes in functions.php, and I personally think excess image generation some devs do is bad practice in general. I will however, often change the image thumbnail sizes in Settings > Media especially if I need large full-width sized images. My tweaks to the default sizes are usually:

  • thumbnail: 150 x 150 max
  • medium: 500 x 500 max
  • large: 1600 x 1100 max

My policy is to never load in an image larger than 2000px wide because when you get past this size, the size of images often blow up and it’s just not worth the extra kB.

  • _Handy tip: WordPress also generates a ‘medium_large’ thumbnail even though it is not explicitly shown in the settings. By default it is tablet size(768px wide) and I’ve actually found it super handy in many cases. For more in depth info, I suggest reading up on the codex._

With the srcset function there really is no need to use the_post_thumbnail() at all in my opinion. I often use srcset in place of background images, using the object-fit: cover CSS property to make sure the image is cropped or contained like a background would be.

Just be aware IE11 does not support object-fit, so if you must support it in your project I suggest using srcset for images only. I’m of the opinion IE 11 is dead and buried however, so I now almost exclusively use object-fit and srcset entirely. ❤️