WordPress : Comment convertir ses images en WebP sans plugin

Illustration WordPress : Comment convertir ses images en WebP sans plugin

Le format WebP, inventé et mis à disposition par Google, est le nouveau format de compression d’image à utiliser. En effet, le leader des moteurs de recherche, voit d’un bon oeil l’utilisation de ce format qui permet un gain d’espace de 30 à 80% selon le fichier d’origine sans perte ou presque. A travers ce tutoriel, nous allons voir comment rendre votre site web WordPress full WebP.

Pourquoi utiliser le format WebP ?

Ce format combine et améliore les avantages des autres formats, la compression du JPG, la transparence du PNG et l’animation du GIF.

WebP PNG JPG GIF
Compression
Compression sans perte
Transparence
Animation

Après des débuts poussifs, le WebP est désormais compatible sur tous les navigateurs (si on considère Internet Explorer comme obsolète et ne devant plus être utilisé) :

Beaucoup de modules WordPress proposent de convertir vos images en WebP, mais ils ne sont généralement capables de convertir que les images qui sont dans la bibliothèque de média. Et dans de nombreux cas, vous pouvez être amené à utiliser des images que la bibliothèque ne reconnaît pas.

Et puis disons le, se dispenser d’un module quand le thème peut s’en occuper, c’est toujours une bonne chose.

Dans ce tutoriel, nous allons donc voir comment programmer une tâche qui scannera les dossiers et convertira les nouvelles images en WebP puis comment faire pour les afficher sur les navigateurs compatibles.

1/ Comment convertir une image JPG/JPEG, PNG, ou GIF en WebP ?

Pour commencer, une petite fonction utilisée pour la conversion d’image, à mettre dans le fichier functions.php par exemple (personnellement j’utilise un fichier à part pour les fonctions « outils ») :

public static function webpImage($source, $quality = 100, $removeOld = false)
    {
        $dir = pathinfo($source, PATHINFO_DIRNAME);
        $name = pathinfo($source, PATHINFO_BASENAME);
        $destination = $dir . DIRECTORY_SEPARATOR . $name . '.webp';
        $info = getimagesize($source);
        $isAlpha = false;

        if ($info['mime'] == 'image/jpeg'||$info['mime'] == 'image/jpg'){
            $image = imagecreatefromjpeg($source);
        }
        elseif ($isAlpha = $info['mime'] == 'image/gif') {
            $image = imagecreatefromgif($source);
        }
        elseif ($isAlpha = $info['mime'] == 'image/png') {
            $image = imagecreatefrompng($source);
        }
        else {
            return $source;
        }
        if ($isAlpha) {
            imagepalettetotruecolor($image);
            imagealphablending($image, true);
            imagesavealpha($image, true);
        }
        imagewebp($image, $destination, $quality);

        if ($removeOld)
            unlink($source);

        return $destination;
    }

2/ Comment scanner de façon récursive le dossier WordPress upload ?

Personnellement, j’évite de laisser WordPress classer les médias par années/mois, ça n’apporte pas grand chose et ça complique la tâche si on souhaite faire un peu de ménage sur son hébergement. Pour cela, il faut aller dans Réglages > Médias et décocher l’option  » Organiser mes téléversements dans des dossiers mensuels et annuels ».

Etant donné que c’est le réglage par défaut, la plupart des dossiers uploads de site WordPress sont déjà organisés ainsi et il est compliqué de revenir en arrière. Pas d’inquiétude nous allons voir comment gérer ce cas de figure.

Voilà la fonction à mettre dans votre functions.php permettant de scanner votre dossier upload et de convertir les images en WebP :

public function webp_conversion_function(){
	$upload_dir=wp_upload_dir();
	$dir = $upload_dir['path']; // ici vous pouvez définir le dossier à scanner. 
        //S'il y a un historique classé mois/année, vous pouvez traiter les dossiers manuellement avant de remettre le dossier d'upload par défaut. Personnellement sur une ancienne installation je fais année par année (ex : path/to/wordpress/wp-content/uploads/2021) pour éviter de planter le serveur et je lance la fonction manuellement (en la plaçant dans le header par exemple). C'est assez rapide et vous n'aurez pas à le refaire. Une fois terminé, vous pouvez remettre le code tel qu'il est ici, la tâche viendra toujours scanner le dossier uploads du moment. Vous pouvez également scanner les fichiers du thème en cours, il peut y avoir quelques images utilisées sur votre site et se trouvant dans le dossier du thème.

	$result = array('files' => array(), 'directories' => array());
	$DirectoryIterator = new RecursiveDirectoryIterator($dir);
	$IteratorIterator = new RecursiveIteratorIterator($DirectoryIterator, RecursiveIteratorIterator::SELF_FIRST);
	foreach ($IteratorIterator as $file) {
		$path = $file->getRealPath();
		if ($file->isDir()) {
			$result['directories'][] = $path;
		} elseif ($file->isFile()) {
			$result['files'][] = $path;
		}
	}
	foreach ($result['files'] as $image) {
		if (!file_exists($image . '.webp') &&  strpos($image,'.webp') === false) {
			webpImage($image); // On appelle la fonction créée précédemment
		}
	}
}

3/ Comment utiliser le moteur cron de WordPress pour programmer une tâche ?

WordPress dispose de son propre moteur de tâche programmée, autant l’utiliser ! La tâche n’étant pas gourmande, je la lance toutes les heures, voici comment (toujours dans functions.php) :

public function webp_conversion_event() {
   if (! wp_next_scheduled('webp_conversion_action')) {
      wp_schedule_event(time(), 'hourly', 'webp_conversion_action');
   }
}
add_action('init', 'webp_conversion_event');
add_action('webp_conversion_action', 'webp_conversion_function');

4/ Comment forcer l’utilisation du format WebP via le htaccess ?

Avec cette méthode, nous allons faire en sorte de forcer l’utilisation du format WebP si le fichier existe et si le navigateur gère ce format. Pour cela vous allez devoir ajouter ces lignes à votre fichier .htaccess se trouvant à la racine de l’installation WordPress.

# BEGIN WebP support
<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
  RewriteRule ^(.+)$ "-" [NC,E=replacewebp:$1.webp]
  RewriteCond %{ENV:replacewebp} !^$
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{QUERY_STRING} !nooptim
  RewriteRule ^(.+)$ %{ENV:replacewebp} [NC,T=image/webp,L]
</IfModule>
<IfModule mod_headers.c>

  # Ajouter le header Vary: Accept pour les images concernées
  # 1) Si une réécriture a eu lieu
  Header merge Vary Accept env=REDIRECT_replacewebp
  # 2) Si une réécriture était possible mais n'a pas eu lieu
  Header merge Vary Accept env=replacewebp

</IfModule>
# END WebP support

Vous voilà maintenant full WebP, et cela améliorera considérablement vos temps de chargement et améliorera vos métriques PageSpeed. Critère à ne surtout pas négliger aux yeux de Google…