Convert JPG and PNG to WebP in WordPress with PHP Code Snippet

Free code snippet to auto convert images to WebP in WordPress

Large image files are a common cause of slow WordPress performance. PageSpeed Insights frequently recommends serving images in next generation formats such as WebP.

Instead of adding another optimization plugin, you can convert images during upload using PHP. This reduces file size at the source, lowers transferred bytes, and improves loading performance without extra overhead.

This guide explains how automatic WebP conversion works, how to implement it using PHP, server requirements, and how to measure real impact.

TL;DR – Jump straight to the code snippet ⬇️

Why WebP improves WordPress performance

WebP was developed by Google to provide smaller file sizes while maintaining visual quality.

According to their official documentation:

  • WebP lossless images are about 26 percent smaller than PNG
  • WebP lossy images are 25 to 34 percent smaller than comparable JPEG files

WebP is supported by modern browsers including Chrome, Edge, Firefox, and Safari.

For image-heavy pages, especially homepage hero sections and landing pages, switching from PNG or JPG to WebP can significantly reduce total page weight.

How image format affects Core Web Vitals

Reducing image size directly influences:

  • Largest Contentful Paint
  • Total transferred bytes
  • Mobile loading performance
  • Bandwidth usage

In one homepage test, replacing large PNG hero images with WebP reduced total page weight by nearly 900 KB without changing hosting, caching, or CDN settings.

No layout changes. No compression adjustments. Only the file format changed.

Each comparison was measured using real landing page assets under controlled conditions to isolate format impact.

On image-heavy landing pages, format changes alone can remove more weight than most caching tweaks.

How PHP converts JPG and PNG to WebP

To convert images during upload, your server must support:

  • GD with WebP enabled
  • or Imagick with WebP support

The process:

  1. Load the original JPG or PNG
  2. Generate a WebP version
  3. Save the new file inside /wp-content/uploads/
  4. Optionally keep the original

If WebP support is not enabled at the server level, PHP cannot generate WebP images.

In most shared hosting environments, GD with WebP support is already available, but it is worth confirming before deployment.

Automatically convert images during upload

You can hook into the WordPress media handling process using the wp_handle_upload filter.

This approach:

  • Detects JPG and PNG uploads
  • Converts them to WebP using GD
  • Prevents filename conflicts
  • Skips GIF files to preserve animation
  • Optionally deletes the original file

Your media workflow remains unchanged, but new uploads are stored and served as WebP automatically.

PHP code snippet to convert JPG and PNG to WebP

Add this snippet to functions.php or a plugin like Fluent Snippet.

This version:

  • Detects JPG and PNG uploads
  • Converts them to WebP using GD or Imagik
  • Adds a -1 suffix to prevent filename conflicts
  • Skips GIF files to preserve animation
  • The WebP quality is intentionally set to default to avoid double compression
/**
 * 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.
 * - Last modified: 1/1/2026
 *
 * @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 '$deleted = unlink($file_path);' (and the following error check)
 * in the wpturbo_handle_upload_convert_to_webp function. (line 110-114)
 * 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;

    // Optimized duplicate check: First check if the original filename exists, then increment
    $base_query = $wpdb->prepare(
        "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s",
        '%' . $wpdb->esc_like($target_extension)
    );
    
    // Fetch all existing filenames with target extension to minimize queries
    $existing_files = $wpdb->get_col($base_query);
    $existing_filenames = [];
    foreach ($existing_files as $file) {
        $file_parts = pathinfo($file);
        $existing_filenames[] = $file_parts['basename'];
    }

    // Check for duplicates efficiently
    while (in_array($new_filename_with_ext, $existing_filenames, true)) {
        $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)) {
            // Log the error for debugging
            error_log('WebP conversion failed: ' . $image_editor->get_error_message());
            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) && isset($saved_image['path']) && 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 (with proper error handling).
            $deleted = unlink($file_path);
            if (!$deleted) {
                error_log("Failed to delete original image: {$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.
            $renamed = rename($file_path, $new_file_path);
            if ($renamed) {
                // 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']);
            } else {
                error_log("Failed to rename duplicate WebP file: {$file_path} to {$new_file_path}");
                // If rename fails, return original upload
                return $upload;
            }
        }
    }

    return $upload;
}

This snippet only affects new uploads. Existing images are deleted.

But if you want to keep the original:

  • Comment out or remove this line in the code: @unlink( $file_path );
  • The file won’t show inside Media Library, but it still stored in /wp-content/uploads/.

Server requirements for WebP conversion

Before enabling automatic conversion:

  • Confirm GD is compiled with WebP support
  • Verify your PHP version supports imagewebp()
  • Test in a staging environment

If WebP encoding is unavailable, the conversion will not run.

If you delete original JPG or PNG files, ensure reliable backups are in place.

Real file size comparison

Flat PNG example

Original PNG: 1 MB
Converted WebP: 34 KB

Flat-color images compress aggressively when converting PNG to WebP..

Wordpress webp conversion comparison file size reduction

Real-world hero image test

To simulate a realistic scenario, I tested a hero mockup previously designed for a landing page.

The file size decreased from 2 MB to 100 KB after converting the image to WebP.

Both images are visually identical. The only variable changed was the file format, from PNG to WebP.

Mockup before png
Mockup after webp

Measuring performance after conversion

After enabling automatic conversion, validate results under consistent conditions.

Use:

  • PageSpeed Insights
  • Lighthouse
  • Chrome Network tab

Evaluate:

  • Largest Contentful Paint
  • Speed Index
  • Total Blocking Time

Test setup

  • Same homepage layout
  • Same VPS with CloudPanel
  • No CDN enabled
  • No caching adjustments
  • Only image format changed

Results

Before conversion, the homepage scored 93 in PageSpeed Insights.

After serving WebP files, the score increased to 100.

In addition:

  • Total page weight decreased
  • Hero image loaded faster
  • Bandwidth usage dropped

Reducing transferred bytes improved performance without infrastructure changes.re remained unchanged, reducing transferred bytes improved overall performance.

Page speed with png
Page speed with webp

WebP vs AVIF in WordPress

Both formats provide strong compression, but trade-offs matter.

AVIF

  • Smaller files in some cases
  • Higher CPU cost during encoding
  • Less consistent hosting support

WebP

  • Strong compression
  • Faster encoding
  • Broad compatibility

For automatic upload processing inside WordPress, WebP offers a reliable balance between compression efficiency and server load. For critical above-the-fold assets such as homepage or landing page hero images, manual AVIF conversion can provide additional file size reduction when tested carefully.

Final thoughts

If your WordPress site relies on large images, converting JPG and PNG files to WebP during upload is one of the most practical structural improvements you can implement.

The performance gains in this guide were achieved without changing hosting, caching, or infrastructure. Only the image format was modified.

When handled at upload level, file size reduction becomes automatic and consistent across your site.

Confirm server support, test in staging, measure the results, and deploy once validated.

Frequently asked questions

Modern WordPress versions allow WebP uploads. Automatic conversion of JPG and PNG depends on server configuration.

Yes. When GD is properly configured, alpha transparency is preserved.

Use the PHP snippet above to convert images to WebP automatically when they are uploaded.

Deleting originals saves disk space. Keeping them allows fallback or future reprocessing. Decide based on your workflow and backup strategy.

Adit MB

Bricks Builder specialist and WordPress web developer focused on performance and search visibility. I build lightweight, responsive websites structured for speed and long term growth.

Adit MB, Co-Founder of Webdivo

Leave the first comment