WordPress and Responsive Images: srcset and sizes Attributes

I’ve been puzzling over a performance issue on one of my sites lately and finally got it figured out today.

A custom shortcode uses the_post_thumbnail() to include a small image (~250px square); I have a bunch of custom image sizes set up, so the srcset attribute included 16 different image sizes. (Overkill? Maybe….) However, instead of using the image closest to 250px wide, Chrome was pulling in the largest available image—sometimes as much as 1500px! Obviously, this is terrible for performance.

In addition, certain pages had dozens of these images, multiplying the effect. My test-case page was 10+MB total (way too heavy…).

Here’s a sample <img> tag for one of my images:

I finally realized that the root cause was that the sizes attribute was set to “100vw,” basically suggesting to the browser that the image might at some point be rendered at 100% width of the viewport, so my browser was happily pulling down the largest possible image so it could display it in all of its high-resolution, hundred-KB glory instead of the scaled dozen-KB file.

Since I know this particular shortcode will only show images at a max width of 250px, I needed to set the sizes attribute to “250px,” hinting to the browser that anything slightly larger than that would be perfectly adequate.

Here’s how I handled it:

  1. Added a filter to wp_get_attachment_image_attributes and checked for a named image size or array
  2. If it was an array, I set the sizes attribute to that pixel size
  3. If it was a named image size, I set the sizes attribute to that pixel size

Sample code:

This approach admittedly is a bit heavy-handed and I’m still testing out the behavior on other pages on the site, but this fixed the problem with that specific shortcode, and my test page went from 10+MB to ~5MB—it cut my page weight in half!

The moral of the story is don’t “set it and forget it,” especially when adding responsive images using custom code.

Thanks to VIA Studio for their blog post that finally made the solution click for me.

WooCommerce Downloadable Products: Granting Permissions to Previous Customers

If you’re using WooCommerce to provide downloadable products and add a new download, previous customers do not automatically get access to it as of v3.x.

Here are a couple of options: Continue reading “WooCommerce Downloadable Products: Granting Permissions to Previous Customers”

Post Type Search Form

Adds a shortcode you can use to show a post type-specific search form.

To use, add [post_type_search_form post_type="post_type_here"] where you want the search form to display.

Get the code at the GitHub repository. Continue reading “Post Type Search Form”

How to Use Backblaze B2 with Sermon Manager for WordPress

If you’re hosting a church website on shared webhosting, chances are they limit how much space and bandwidth you can use each month. Uploading sermons each week can eat into those limits very quickly.

Enter Backblaze B2, a cloud storage option costs less than a quarter of what Amazon S3 would cost for the same amount of storage. Backblaze has been around for years as a computer backup solution and has made their name by providing reliable storage at low cost.

In fact, the first 10GB of storage is free, so you might even be able to host your sermons at no cost at all. Continue reading “How to Use Backblaze B2 with Sermon Manager for WordPress”

WPForms: Force Async Scripts

This little plugin has one job: make WPForms’ Google Recaptcha script load asynchronously.

Get the plugin on GitHub.

Installation Instructions

  1. Copy the wpforms-recaptcha-async.php file to your wp-content/plugins/ directory (or compress to a zip file and upload in the WordPress backend “Plugins > Add New”
  2. Activate
  3. That’s it. All the merged scripts will be loaded with the async and defer attributes.

Merge + Minify + Refresh: Force Async Scripts

This little plugin has one job: make all merged scripts produced by the Merge + Minify + Refresh plugin load asynchronously.

Get the plugin on GitHub.

Installation Instructions

  1. Copy the merge-minify-refresh-async.php file to your wp-content/plugins/ directory (or compress to a zip file and upload in the WordPress backend “Plugins > Add New”
  2. Activate
  3. That’s it. All the merged scripts will be loaded with the async attribute.

Potential Issues

Note that if you have plugins or other code that adds inline Javascript, it probably will break if it’s depending on jQuery (for example) to be loaded and active already.

One workaround is to exclude /wp-includes/js/jquery/jquery.js from the Merge + Minify + Refresh cache, but you may have to exclude other scripts as well.

Woo Generate New Password Reset Link

If your site auto-generates customer credentials, then they receive their username and password in plaintext in their email.

To improve security and make the experience a bit more user-friendly, this plugin sends users a link to create their password, much like WordPress core does when you add a new user account.

Get the code at the WordPress plugin repository, or open issues at the GitHub repository. Continue reading “Woo Generate New Password Reset Link”

Contact Form 7 to Robly

Adds Contact Form 7 submissions to Robly, with options to specify the list(s) and custom fields.

Get the code at the WordPress plugin repository, or open issues at the GitHub repository. Continue reading “Contact Form 7 to Robly”