What is a good alternative to using $content_width for image optimization?

The $content_width GLOBAL in WordPress effects many themes and even some plugins by limiting the size of images and embeds in posts, it is a requirement for themes submitted to wordpress.org.

It is set by using:

$content_width = 584; // Twenty Twelve example

If you insert a large image (default 1024×1024) into a post it results in:

src="https://wordpress.stackexchange.com/questions/86950/wp-content/uploads/2013/02/IMG_1390-1024x682.jpg" width="584" height="328"

If instead you remove this global setting and insert the actual image size, set with add_image_size it results in:

src="https://wordpress.stackexchange.com/questions/86950/wp-content/uploads/2013/02/IMG_13901-584x328.jpg" width="584" height="328" 

Removing the global and inserting large images, which is very common, often results in a saving of over 2x, in pages with multiple images I see hundreds of KB saved on page load.

Is using add_image_size and removing the ability to insert full size images not a better option?

ps. I wrote about it here with more accurate data


Keep in mind that the $content_width global is not only used for images, but also for embedded objects, such as video. So, any solution won’t merely be a case of dropping use/support of $content_width itself.

Usually a Theme will constrain content-area images in a few ways:

  1. Large Image size: Defining $content_width something appropriate for the Theme design
  2. Original/Full Image size: Defining a CSS rule for #content img { max-width: XXX; height: auto; } to ensure that full-size images that get inserted don’t break the layout
  3. Thumbnail Image size: Calling set_post_thumbnail_size() to define the Featured Image/Post Thumbnail default thumbnail size. (Note: I do not personally recommend using this method. Define custom image sizes specific to a given location for a featured image, and then call that custom size in the specific template location, via the_post_thumbnail( $size ).)

As you have discovered, because of the way WordPress selects with intermediate image size to use for any given image request, that request could result in a browser-scaled image.

Theme-Defined Values for Large Image

One option would be to redefine the settings for large image dimensions. (Proceed with caution. This is fine for your own site, but a publicly distributed Theme that messes with user configuration settings is… gray area at best.)

The large image dimension settings are stored as:

$large_image_width = get_option( 'large_size_w' );
$large_image_height = get_option( 'large_size_h' );

So, you could set those values according to your $content_width value:

global $content_width;
update_option( 'large_size_w', $content_width );
update_option( 'large_size_h', $content_width );

(Of course, you’d want to put some failsafe/error-checking around this, as appropriate.)

Remove Option to Insert Full-Sized Images

If you simply want to prevent users from inserting full-size images (again: proceed with caution; this may be Plugin territory), you can filter 'image_size_names_choose':

function wpse86950_filter_image_size_names_choose( $possible_sizes ) {
    unset( $possible_sizes['full'] );
    return $possible_sizes;
add_filter( 'image_size_names_choose', 'wpse86950_filter_image_size_names_choose' );

Again: you may want to add some sane failsafes here, as this filter is used in more than one place.

Define a custom image size for full-post-width images

Related to the previous option, you can define a 'full-post-width' image size:

global $content_width;
add_image_size( 'full-post-width', $content_width, $content_width, false );

Then, add it to the list of available options:

function wpse86950_filter_image_size_names_choose( $possible_sizes ) {
    // Unset full image size
    unset( $possible_sizes['full'] );
    // Add full-post-width image size
    $possible_sizes['full-post-width'] = 'Full Post Width';
    // Return array
    return $possible_sizes;
add_filter( 'image_size_names_choose', 'wpse86950_filter_image_size_names_choose' );

Leave a Comment