TL;DRJump straight to the code snippet ⬇️

As a WordPress web developer focused on speed and SEO, I’m always searching for ways to make websites faster without bloating them with unnecessary plugins.

One of the most effective methods to improve load time is to automatically convert images to WebP—a format that offers smaller file sizes without compromising quality.

This post is a follow-up to my article on How To Increase Page Load Speed In WordPress. If you haven’t read it yet, check it out for more speed optimization tips.

Why WebP Is Better Than JPG Or PNG

If you care about website performance—and you should—switching from JPG or PNG to WebP can significantly speed up your WordPress site.

Benefits of WebP:

  • Modern Browser Support – Almost all major browsers now support WebP, so compatibility issues are rare.
  • Smaller File Size – WebP files are typically 30–50% smaller than JPEG or PNG without noticeable quality loss.
  • Better SEO Performance – Google favors fast-loading websites, so optimized images can help boost your rankings.
  • Google-Recommended – Tools like Google PageSpeed Insights suggest serving images in modern formats like WebP.

In a recent client project, simply converting images to WebP noticeably improved site speed—no other major changes required.

The WebP Conversion Code Snippet

This snippet, originally by Mark Harris and slightly modified by me, automatically converts uploaded JPGs and PNGs to WebP.

Modifications I Made:

  • Adds a -1 suffix if the same image is uploaded twice.
  • Skips .gif files to preserve animations and prevent conversion issues.
<?php

/**
 * Convert Uploaded Images to WebP Format
 *
 * This snippet converts uploaded images (JPEG & PNG) to WebP format
 * automatically in WordPress. Ideal for use in a theme's functions.php file,
 * or with plugins like Code Snippets or WPCodeBox.
 *
 * @package     WordPress_Custom_Functions
 * @author      Mark Harris
 * @link        www.christchurchwebsolutions.co.uk
 *
 * Modification:
 * - Added a counter to the filename for duplicate uploads and remove .gif
 * - Excludes already uploaded WebP images from conversion.
 * - Checks for duplicate filenames across the entire media library, not just the current folder.
 * - Optimized for performance.
 *
 * @author      Adit MB
 * @link        https://webdivo.com
 *
 * Usage Instructions:
 * - Add this snippet to your theme's functions.php file, or add it as a new
 * snippet in Code Snippets or WPCodeBox.
 * - The snippet hooks into WordPress's image upload process and converts
 * uploaded images to the WebP format.
 *
 * Optional Configuration:
 * - By default, the original image file is deleted after conversion to WebP.
 * If you prefer to keep the original image file, simply comment out or remove
 * the line '@unlink( $file_path );' in the wpturbo_handle_upload_convert_to_webp function.
 * This will preserve the original uploaded image file alongside the WebP version.
 */

add_filter('wp_handle_upload', 'wpturbo_handle_upload_convert_to_webp');

function wpturbo_handle_upload_convert_to_webp($upload)
{
    // Determine if the uploaded image is a type we can convert (JPG, PNG)
    $is_convertible = in_array($upload['type'], ['image/jpeg', 'image/png'], true);
    // Determine if the uploaded image is already a WebP.
    $is_webp = ($upload['type'] === 'image/webp');

    // If the file type is not a convertible image or a WebP, do nothing.
    if (!$is_convertible && !$is_webp) {
        return $upload;
    }

    // Get file path information.
    $file_path = $upload['file'];
    $file_info = pathinfo($file_path);
    $dirname   = $file_info['dirname'];
    $filename  = $file_info['filename']; // Filename without extension.

    // For convertible types, the target is .webp. For existing WebP, it's the original extension.
    $target_extension = $is_convertible ? '.webp' : '.' . $file_info['extension'];

    // --- Global Duplicate Filename Check ---
    global $wpdb;
    $new_filename_base = $filename;
    $counter = 1;
    $new_filename_with_ext = $new_filename_base . $target_extension;

    // Loop to find a unique name across the entire media library.
    // This is more reliable than file_exists() as it checks the database for the filename.
    while ($wpdb->get_var($wpdb->prepare(
        "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s",
        '%' . $wpdb->esc_like($new_filename_with_ext)
    )) > 0) {
        $new_filename_base = $filename . '-' . $counter;
        $new_filename_with_ext = $new_filename_base . $target_extension;
        $counter++;
    }

    // This is the unique path for our final file.
    $new_file_path = $dirname . '/' . $new_filename_with_ext;

    // --- Handle Conversion for JPG/PNG ---
    if ($is_convertible) {
        // Check if ImageMagick or GD is available.
        if (!extension_loaded('imagick') && !extension_loaded('gd')) {
            return $upload; // Cannot convert, return original.
        }

        $image_editor = wp_get_image_editor($file_path);
        if (is_wp_error($image_editor)) {
            return $upload; // Editor error, return original.
        }

        // Attempt to save the image in WebP format to the unique path.
        $saved_image = $image_editor->save($new_file_path, 'image/webp');
        if (!is_wp_error($saved_image) && file_exists($saved_image['path'])) {
            // Success: replace the uploaded image with the WebP image.
            $upload['file'] = $saved_image['path'];
            $upload['url']  = str_replace(basename($upload['url']), basename($saved_image['path']), $upload['url']);
            $upload['type'] = 'image/webp';

            // Optionally remove the original image.
            @unlink($file_path);
        }
        // If saving fails, we fall through and return the original $upload array.

    // --- Handle Renaming for duplicate WebP ---
    } elseif ($is_webp) {
        // If the unique path is different from the original path, a duplicate was found.
        if ($new_file_path !== $file_path) {
            // Rename the physical file.
            if (rename($file_path, $new_file_path)) {
                // Success: update the upload array with the new path and URL.
                $upload['file'] = $new_file_path;
                $upload['url']  = str_replace(basename($upload['url']), basename($new_file_path), $upload['url']);
            }
            // If rename fails, we fall through and return the original $upload.
        }
    }

    return $upload;
}

How To Use This Snippet

  • Check Hosting Support – Ensure your hosting has GD or Imagick extensions enabled (most do).
  • Add The Code – Paste it into your functions.php file or use a code snippet plugin (I recommend Fluent Snippet or WPCodeBox).
  • Remove <?php If Necessary – If your file already starts with <?php, don’t add it again.
  • Enable The Snippet – Activate it in your code snippet plugin or theme.

✅ Once enabled, new image uploads will automatically be converted to WebP—reducing file size and improving load speed.
⚠️ Note: This only applies to new uploads, not existing images.

Example: WebP Conversion In Action

I tested this by uploading two identical images—one with the snippet active and one without. The WebP version was noticeably smaller in file size, proving the speed benefit.

Wordpress webp conversion comparison file size reduction

Optional: Keep The Original Image

By default, the snippet removes the original file after conversion (recommended for saving space).

If you want to keep the original:

  • Add // or # before this line in the code: @unlink( $file_path );
  • Or remove the line entirely.
  • The original won’t show in the WordPress media library but will still exist in /wp-content/uploads/.

Why I Still Prefer WebP Over AVIF

AVIF offers even better compression than WebP (sometimes), but WebP is still safer for most WordPress projects:

  • Better Browser Support – AVIF support is growing but still inconsistent on older browsers.
  • Compatibility With Tools – WebP is integrated into most image optimization plugins and CMS platforms.
  • Reliable Quality – AVIF can sometimes produce artifacts under heavy compression, while WebP strikes a good balance between quality and file size.

For now, WebP is the most practical, stable, and SEO-friendly choice for WordPress developers.

Final Thoughts

From my testing across multiple client sites, automatically converting images to WebP is one of the easiest, most effective speed optimizations you can make in WordPress. This snippet is lightweight, requires no extra plugins, and consistently delivers smaller file sizes without hurting quality. Implement it, run your own speed tests, and you’ll see the difference immediately.

Leave the first comment