webp Optimierung für alle – mit Fallback

webp Optimierung für alle – mit Fallback

Wer ohne lästige Plugins für nahezu alle Online-Shops und Webanwendungen wie WordPress zügig auf webp-Dateien umstellen möchte steht vor zwei Problemen. Darunter die schiere Menge an Dateien und natürlich das Problem mit der Rückwärtskompatabilität mit älteren Browsern und Geräten.

Nach einigen Tests kann ich heute eine praktische Lösung für nahezu alle Systeme vorstellen. Hierzu wird lediglich die .htaccess Datei angepasst und ein PHP-Script zur Generierung der webp-Dateien verwendet.

Das PHP-Script benötigt eine ausreichend lange Ausführungszeit. Es erstellt in allen Ordnern eine webp-Datei für jede Bilddatei. Bei einigen Bilddateien funktioniert dies jedoch nicht.

Ich empfehle auf jeden Fall Backups und ausreichende Tests vor einem produktiven Einsatz.

PHP-Script:

<?php
ini_set('opcache.enable', 0);
ini_set('opcache.enable_cli', 0);

$allowed_file_types = array('jpg', 'jpeg', 'png');

$webp_quality = 80;

function create_webp($source, $destination, $quality) {
    try {
        $image = imagecreatefromstring(file_get_contents($source));
        if (!$image) {
            error_log('Failed to create image resource from file: ' . $source);
            return false;
        }
        if (!imageistruecolor($image)) {
            // Skip paletted images
            error_log('Skipping paletted image: ' . $source);
            imagedestroy($image);
            return false;
        }
		
       if (file_exists($destination) && !unlink($destination)) {
    chmod($destination, 0755); // Set file permission to 755
    error_log('Failed to remove existing WebP file: ' . $destination);
    imagedestroy($image);
    return false;
}

        if (preg_match('/\.png$/i', $source)) {
            $tmp_png = tempnam(sys_get_temp_dir(), 'png');
            if (!$tmp_png || !imagepng($image, $tmp_png)) {
                error_log('Failed to write PNG file to disk: ' . $tmp_png);
                imagedestroy($image);
                return false;
            }
            $image = imagecreatefrompng($tmp_png);
            if (!$image) {
                error_log('Failed to create image resource from PNG file: ' . $tmp_png);
                unlink($tmp_png);
                return false;
            }
            unlink($tmp_png);
        }
        $result = imagewebp($image, $destination, $quality);
        imagedestroy($image);
		
        if (!$result) {
            error_log('Failed to create WebP file: ' . $destination);
            return false;
        }
    } catch (Exception $e) {
        error_log('Caught exception while converting image: ' . $source . ' (' . $e->getMessage() . ')');
        return false;
    }

    if (!file_exists($destination)) {
        error_log('WebP file not created: ' . $destination);
        return false;
    }

    return true;

}

function scan_directory($directory, $allowed_file_types, $webp_quality) {
    $files = scandir($directory);
    foreach ($files as $file) {
        $file_path = $directory . '/' . $file;
        if (is_file($file_path) && in_array(pathinfo($file_path, PATHINFO_EXTENSION), $allowed_file_types)) {
            $webp_path = pathinfo($file_path, PATHINFO_DIRNAME) . '/' . pathinfo($file_path, PATHINFO_FILENAME) . '.webp';
            if (!file_exists($webp_path)) {
                create_webp($file_path, $webp_path, $webp_quality);
            }
        } elseif (is_dir($file_path) && $file != '.' && $file != '..') {
            scan_directory($file_path, $allowed_file_types, $webp_quality);
        }
    }
}

scan_directory('.', $allowed_file_types, $webp_quality);

echo 'done';

?>

Die .htaccess Datei prüft ob der Browser webp unterstützt und ob eine webp-Datei vorhanden ist.

<IfModule mod_rewrite.c>
  RewriteEngine On

  # Check if browser supports WebP images
  RewriteCond %{HTTP_ACCEPT} image/webp

  # Check if WebP replacement image exists
  RewriteCond %{DOCUMENT_ROOT}/$1.webp -f

  # Serve WebP image instead
  RewriteRule (.+)\.(jpe?g|png|gif)$ $1.webp [T=image/webp,E=REQUEST_image]
</IfModule>

<IfModule mod_headers.c>
  # Vary: Accept for all the requests to jpeg, png and gif
  Header append Vary Accept env=REQUEST_image
</IfModule>

<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>

Der .htaccess Part stammt von https://github.com/vincentorback/WebP-images-with-htaccess

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert