0Wordpress LogoAutomatische Generierung und Bereitstellung von Avif-Bildern mit WordPress

Ich habe ziemlich viel Zeit damit verbracht, die Leistung dieser Site zu optimieren, und als Teil der laufenden Arbeit beobachte ich neue Technologien, die dazu beitragen könnten, die Geschwindigkeit für Besucher zu verbessern. Ich verfolge seit einiger Zeit die Einführung von Bildformaten der nächsten Generation und mit der Unterstützung durch Webbrowser, die jetzt ziemlich weit verbreitet sind, war es an der Zeit herauszufinden, wie man diese neuen Formate in WordPress nutzen kann.

Es sind mehrere Schritte erforderlich, die ich unten in Überschriften unterteilt habe

Unterstützung in nginx aktivieren

Der erste Schritt besteht darin, Ihren Webserver zu aktivieren (in meinem Fall nginx) um die Mime-Typen der neuen Formate zu erkennen. Dazu müssen Sie mime.types bearbeiten, das Sie wahrscheinlich unter /etc/nginx/mime.types finden. Ich habe den folgenden Abschnitt hinzugefügt

/ Inhalte verstoßen gegen die Regeln verstoßen gegen die Regeln;
image/heif heif;
Bild/Heic-Sequenz heics;
Bild/Heif-Sequenz heifs;
image/avif avif;
Bild-/Avif-Sequenz-Überprüfung;
image / jxl jxl;

Dateien automatisch bereitstellen, wo sie verfügbar sind

Der nächste Schritt besteht darin, nginx anzuweisen, Dateien automatisch bereitzustellen, wann immer sie vorhanden sind (und auf ältere Formate zurückzugreifen, bei denen keine neue Formatdatei vorhanden ist)
Bearbeiten Sie dazu zuerst die nginx-Hauptkonfigurationsdatei (normalerweise /etc/nginx/nginx.conf) und fügen Sie den folgenden Abschnitt in das http{} Abschnitt der Konfiguration

Karte $http_accept $img_ext
{
   ~ Bild / jxl '.jxl';
   ~image/avif '.avif';
   ~image/webp '.webp';
   Standard      '';
}

Beachten Sie, dass ich nur versuche, jxl . bereitzustellen (JPEG-XL) oder avif-Dateien, Sie könnten weitere Optionen hinzufügen (in der reihenfolge der präferenz!) wenn Sie wünschen.
Nächste, Sie müssen Folgendes unter dem Server hinzufügen{} Abschnitt der nginx-Konfiguration (die sich in der Hauptkonfigurationsdatei oder in einer separaten Konfigurationsdatei befinden kann, je nachdem, wie Sie Ihre nginx-Konfigurationsstruktur eingerichtet haben)

Standort ~* ^.+.(png|jpg|jpeg)$
{
   add_header Variieren Akzeptieren;
   try_files $uri$img_ext $uri =404;
}

Jetzt sucht nginx nach image.jpg.jxl und dann nach image.jpg.avif und dann nach image.jpg.webp und schließlich nach image.jpg, wenn es von allen Browsern, die die neueren Formate unterstützen, nach image.jpg gefragt wird. Als nächstes müssen wir sie in WordPress aktivieren

Aktivieren Sie Next-Gen-Formate in WordPress

Fügen Sie Ihrer functions.php den folgenden Code hinzu (Mache dies idealerweise in einem Child-Theme, damit deine Änderungen nicht überschrieben werden, wenn du dein Theme aktualisierst)

/***************************************************\
* Ermöglichen SVG Unterstützung und andere moderne Bildformate *
\***************************************************/
Funktion cc_mime_types( $Pantomimen )
{
   $Pantomimen['svg'] = 'image/svg+xml';
   $Pantomimen['webp'] = 'image/webp';
   $Pantomimen["Verletzen"] = "Image / Unskill'd ';
   $Pantomimen['heif'] = 'Bild/Heif';
   $Pantomimen['verhexen'] = "Image / Verstoß gegen die Regelreihenfolge ';
   $Pantomimen['Heifen'] = 'Bild/Heif-Sequenz';
   $Pantomimen['avif'] = 'image/avif';
   $Pantomimen['beachten'] = 'image/avif-sequenz';
   $Pantomimen['jxl'] = 'image/jxl';
   zurück $mimes;
}
add_filter( 'upload_mimes', 'cc_mime_types' );

Beachten Sie, dass ich auch die Unterstützung für . aktiviert habe SVG Bilder gleichzeitig

Jetzt können Sie Bilder im Next-Gen-Format hochladen und sie direkt in WordPress verwenden, wenn Sie möchten, aber ich empfehle dies nicht, da viele ältere Browser sie noch nicht unterstützen – und wir haben nginx bereits eingerichtet, um sie intelligent zu bedienen, also sollten wir das nutzen. Was wir tun möchten, ist, die neuen Formate automatisch zu generieren, wenn wir Bilder hochladen (es gibt bereits Plugins, die dies für webp tun, aber noch nichts was es für jxl oder avif tut).

libheif installieren

Dieser Schritt erfordert Zugriff auf die Befehlszeile Ihres Webhosts, was einfach ist, wenn du a läufst VPS, Dies ist jedoch möglicherweise nicht so einfach, wenn Sie auf Shared Hosting arbeiten. In diesem Fall müssen Sie möglicherweise Ihren Host um Unterstützung bitten
Führen Sie die folgenden Bash-Befehle aus (diese sind ausgewählt für Centos 8, andere Distributionen können etwas anders sein)

dnf -y install --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm
dnf -y installiere libheif

Benutzerdefinierte Funktion zu WordPress Functions.php hinzufügen, um alle hochgeladenen Bilder zu komprimieren (und ihre Thumbnails) zum avif-Format

Wie beim vorherigen Schritt functions.php empfehle ich, dies in einem Child-Theme hinzuzufügen

/*****************************\
* Konvertieren Sie png und jpg in avif *
\*****************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
Funktion jps_compress_img( $Metadaten, $Anhang_ID )
{
   // Dateipfad von ID abrufen
   $filepath= get_attached_file($Anhang_ID);

   // ist die datei ein png oder jpeg
   wenn(Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="jpg" || Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="jpeg" || Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="png")
   {
      // Wenn ja, Führen Sie die Komprimierung der Hauptdatei zu avif . aus
      shell_exec("heif-enc $filepath -o $filepath.avif -q 50 -A");
      $Teile = preg_split('~/(?=[^/]*$)~', $Dateipfad);

      // Führen Sie dann die Komprimierung der Miniaturansichten zu avif . aus
      $thumbpaths = $metadaten['Größen'];
      für jede ($Daumenpfade als $key => $Daumen)
      {
          $daumenpfad= $daumen['Datei'];
          $thumbfullpath= $parts[0] . "/" . $Daumenpfad;
          shell_exec("heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -A");
      }
   }
   // gib zurück was wir haben
   $metadaten zurückgeben;
}

//Vergessen Sie nicht, die Avifs zu löschen, wenn die Anhänge gelöscht werden
Funktion jps_delete_avif($Anhang_ID)
{
   $all_images= get_intermediate_image_sizes($Anhang_ID);
   für jede($all_images als $each_img)
   {
      $each_img_det= wp_get_attachment_image_src($Attach_id,$jedes_img);
      $each_img_path= ABSPATH.'wp-content'.substr($each_img_det[0],strpos($each_img_det[0],"/Uploads/")).'.avif';
      shell_exec("rm -f $each_img_path");
   }
}
add_action( 'delete_attachment', 'jps_delete_avif' );

Derzeit ist es soweit – alle hochgeladenen Bilder werden in Avif-Kopien umgewandelt (unter Beibehaltung der Originale). Sie können alle Ihre Bilder regenerieren, um die Avif-Dateien zu erstellen, indem Sie ein Plugin verwenden using. Hinweis – Ich habe es noch nicht eingerichtet JPEG-XL-Komprimierung als Unterstützung dafür ist in Mainstream-Browsern noch nicht verfügbar (Obwohl es sich in Prerelease-Browsern befindet, wird es sehr bald kommen).

Während ich mich mit Formaten und Optimierung der nächsten Generation beschäftige, habe ich einen letzten Tipp – Komprimieren SVG Bilder mit gzip (oder noch besser zopfli und brotli). Dazu ist eine weitere benutzerdefinierte Funktion erforderlich…

Bonus: SVG Kompression

/*************************************************\
* Kompresse SVG Bilder mehr mit Brotli und Zopfli *
\*************************************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_vectors', 10, 2 );
Funktion jps_compress_vectors( $Metadaten, $Anhang_ID )
{
    // Dateipfad von ID abrufen
    $filepath= get_attached_file($Anhang_ID);

    // ist die datei ein svg
    wenn(Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="svg")
    {
       // Wenn ja, Führen Sie die Komprimierung mit zopfli und brotli . aus
       shell_exec("zopfli --gzip $filepath");
       shell_exec("brotli --best --output=$filepath.br $filepath");
    }

    // gib zurück was wir haben
    $metadaten zurückgeben;
}

Beachten Sie, dass in Ihrer nginx-Konfiguration gzip_static und brotli_static aktiviert sein müssen.

Selbstkompilieren für eine neuere Version

Ich habe festgestellt, dass auf Centos die neueste Version von heif-enc ist 1.7 was einige Fehler beim Erstellen von Avifs hat. Also habe ich mich entschieden, mein eigenes neueres zu kompilieren (1.12) baue und verwende das stattdessen. Dies war etwas kompliziert, da der aom-Codec als gemeinsam genutzte Bibliothek erforderlich war. Führen Sie dazu die folgenden Bash-Befehle aus. Stellen Sie sicher, dass Sie sie als normaler Benutzer ausführen, nicht als Root-Benutzer. Beachten Sie auch, dass einige dieser Befehle möglicherweise nicht unbedingt erforderlich sind, Es hat eine Weile gedauert, bis es funktionierte, und ich habe mir nur notiert, was funktioniert - ich bin keineswegs ein Linux-Experte!

dnf installieren x265 x265-devel svt-av1
CXXFLAGS= . exportieren"$CXXFLAGS -fPIC"
cd ~

Git-Klon https://aomedia.googlesource.com/aom
mkdir -p aom_build
cd aom_build
cmake ~/aom -DBUILD_SHARED_LIBS=true
machen
sudo machen installieren
cp ./libaom.so.3 /usr/bin/local/libaom.so.3

cd ~
export PKG_CONFIG_PATH=~/aom_build/
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/aom_build/
LD_LIBRARY_PATH exportieren

git clone --recurse-submodules --recursive https://github.com/strukturag/libheif.git
cd libheif
./autogen.sh
./konfigurieren
machen
sudo machen installieren

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lokal/bin/
LD_LIBRARY_PATH exportieren

Sobald du das getan hast, Stellen Sie sicher, dass es funktioniert, indem Sie es ausführen php -a und den folgenden Befehl ausführen

shell_exec("/usr/local/bin/heif-enc -A");

Sie sollten eine vollständige Ausgabe erhalten, nicht nur a 1 Leitungsfehler. Angenommen, das funktioniert in Ordnung, können Sie Ihre functions.php so ändern, dass jede der Shell-exec-Referenzen auf /usr/local/bin/heif-enc statt nur auf heif-enc verweist

/*****************************\
* Konvertieren Sie png und jpg in avif *
\*****************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
Funktion jps_compress_img( $Metadaten, $Anhang_ID )
{
   // Dateipfad von ID abrufen
   $filepath= get_attached_file($Anhang_ID);

   // ist die datei ein png oder jpeg
   wenn(Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="jpg" || Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="jpeg" || Pfadinfo($Dateipfad, PATHINFO_EXTENSION)=="png")
   {
      // Wenn ja, Führen Sie die Komprimierung der Hauptdatei zu avif . aus
      shell_exec("/usr/local/bin/heif-enc $filepath -o $filepath.avif -q 50 -A");
      $Teile = preg_split('~/(?=[^/]*$)~', $Dateipfad);

      // Führen Sie dann die Komprimierung der Miniaturansichten zu avif . aus
      $thumbpaths = $metadaten['Größen'];
      für jede ($Daumenpfade als $key => $Daumen)
      {
          $daumenpfad= $daumen['Datei'];
          $thumbfullpath= $parts[0] . "/" . $Daumenpfad;
          shell_exec("/usr/local/bin/heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -A");
      }
   }
   // gib zurück was wir haben
   $metadaten zurückgeben;
}

Leave a Reply