0Logo WordpressGenera e servi automaticamente immagini avif con wordpress

Ho dedicato molto tempo all'ottimizzazione delle prestazioni di questo sito, e come parte del lavoro in corso monitoro le nuove tecnologie che potrebbero aiutare a migliorare la velocità dei visitatori. Seguo da un po' l'adozione di formati immagine di nuova generazione e con il supporto dei browser web ormai abbastanza diffuso era giunto il momento di capire come utilizzare questi nuovi formati in wordpress.

Sono necessari più passaggi che ho suddiviso in titoli di seguito

Abilita il supporto in nginx

Il primo passo è abilitare il tuo server web (nel mio caso nginx) riconoscere i tipi mime dei nuovi formati. Per fare ciò è necessario modificare mime.types che è probabile che si trovi in ​​/etc/nginx/mime.types. Ho aggiunto la seguente sezione

/ i contenuti violano le regole violano le regole;
immagine/heif heif;
immagine/heic-sequenza heics;
immagini/sequenza di file heifs;
immagine/avif avif;
image / recensione avif-sequence;
immagine / jxl jxl;

Servi automaticamente i file dove sono disponibili

Il prossimo passo è dire a nginx di servire i file automaticamente ogni volta che esistono (e per ricorrere a formati precedenti in cui non esiste un nuovo file di formato)
Per fare ciò, prima modifica il file di configurazione principale di nginx (di solito /etc/nginx/nginx.conf) e aggiungi la seguente sezione all'interno di http{} sezione della configurazione

mappa $http_accept $img_ext
{
   ~ immagine / jxl '.jxl';
   ~immagine/avif '.avif';
   ~immagine/webp '.webp';
   predefinito      '';
}

Nota che sto solo cercando di servire jxl (JPEG-XL) o file avif, potresti aggiungere più opzioni (in ordine di preferenza!) se desideri.
Prossimo, è necessario aggiungere quanto segue sotto il server{} sezione della configurazione di nginx (che può essere nel file di configurazione principale o può essere in un file di configurazione separato a seconda di come hai impostato la struttura di configurazione di nginx)

posizione ~* ^.+.(png|jpg|jpeg)$
{
   add_header Varia Accetta;
   try_files $uri$img_ext $uri =404;
}

Ora nginx cercherà image.jpg.jxl e poi image.jpg.avif e poi image.jpg.webp e infine image.jpg quando viene richiesto image.jpg da qualsiasi browser che supporta i formati più recenti. Quindi dobbiamo abilitarli in wordpress

abilita i formati di nuova generazione in wordpress

Aggiungi il seguente codice al tuo functions.php (idealmente fallo in un tema figlio in modo che quando aggiorni il tema le tue modifiche non vengano sovrascritte)

/***************************************************\
* Permettere SVG supporto e altri formati di immagine moderni *
\***************************************************/
funzione cc_mime_types( $mimi )
{
   $mimi['svg'] = 'immagine/svg+xml';
   $mimi['webp'] = 'immagine/webp';
   $mimi["Violare"] = "Immagine / non qualificata";
   $mimi['gioco'] = 'immagine/testa';
   $mimi['esadecimale'] = "Immagine / viola la sequenza delle regole ';
   $mimi['giochetti'] = 'immagine/sequenza-heif';
   $mimi['avif'] = 'immagine/avif';
   $mimi['Avviso'] = 'immagine/sequenza-avif';
   $mimi['jxl'] = 'immagine / jxl';
   restituire $mimi;
}
add_filter( 'carica_mimi', 'cc_mime_types' );

Nota che ho anche abilitato il supporto per SVG immagini allo stesso tempo

Ora puoi effettivamente caricare immagini in formato di nuova generazione e usarle direttamente in wordpress se lo desideri, ma non lo consiglio perché molti browser più vecchi non li supportano ancora - e abbiamo già impostato nginx per servirli in modo intelligente, quindi dovremmo usarlo. Quello che vogliamo fare è generare automaticamente i nuovi formati quando carichiamo le immagini (ci sono già plugin che lo fanno per webp, ma niente che lo faccia ancora per jxl o avif).

Installa libheif

Questo passaggio richiede l'accesso alla riga di comando del tuo host web, che è semplice se corri a VPS, ma potrebbe non essere così semplice se utilizzi un hosting condiviso, nel qual caso potresti dover chiedere supporto al tuo host
Esegui i seguenti comandi bash (questi sono selezionati per centos 8, altre distribuzioni potrebbero essere leggermente diverse)

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 install libheif

Aggiungi una funzione personalizzata a wordpress functions.php per comprimere tutte le immagini caricate (e le loro miniature) in formato avif

Come per il precedente passaggio functions.php, consiglio di aggiungerlo in un tema figlio

/*****************************\
* Converti png e jpg in avif *
\*****************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
funzione jps_compress_img( $metadati, $id_allegato )
{
   // ottieni il percorso del file da id
   $filepath= get_attached_file($id_allegato);

   // il file è un png o jpeg
   Se(informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="jpg" || informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="jpeg" || informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="png")
   {
      // Se è così, esegui la compressione del file principale su avif
      shell_exec("heif-enc $percorsofile -o $percorsofile.avif -q 50 -UN");
      $parti = preg_split('~/(?=[^/]*$)~', $percorso del file);

      // Quindi esegui la compressione delle miniature su avif
      $thumbpaths = $metadati['taglie'];
      per ciascuno ($thumbpaths come $key => $pollice)
      {
          $thumbpath= $thumb['file'];
          $thumbfullpath= $parts[0] . "/" . $thumbpath;
          shell_exec("heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -UN");
      }
   }
   // restituisci quello che abbiamo
   restituisce $metadati;
}

//non dimenticare di eliminare gli avif se gli allegati vengono eliminati
funzione jps_delete_avif($id_allegato)
{
   $all_images= get_intermediate_image_sizes($id_allegato);
   per ciascuno($all_images come $each_img)
   {
      $each_img_det= wp_get_attachment_image_src($allega_id,$ogni_img);
      $each_img_path= ABSPATH.'wp-content'.substr($each_img_det[0],strpos($each_img_det[0],"/caricamenti/")).'.avif';
      shell_exec("rm -f $each_img_path");
   }
}
add_action( 'cancella_allegato', 'jps_delete_avif' );

Al momento è così: tutte le immagini che carichi verranno convertite in copie avif (con gli originali conservati). Puoi rigenerare tutte le tue immagini per creare i file avif usando un plugin. Nota: non ho ancora configurato yet JPEG-La compressione XL poiché il supporto non è ancora disponibile nei browser tradizionali (anche se è nei browser prerelease, quindi arriverà molto presto).

Mentre sto trattando i formati di nuova generazione e l'ottimizzazione, ho un ultimo consiglio: comprimere SVG immagini con gzip (o ancora meglio zopfli e brotli). Per farlo è necessaria un'altra funzione personalizzata...

Bonus: SVG compressione

/*************************************************\
* Comprimere SVG immagini di più con brotli e zopfli *
\*************************************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_vectors', 10, 2 );
funzione jps_compress_vectors( $metadati, $id_allegato )
{
    // ottieni il percorso del file da id
    $filepath= get_attached_file($id_allegato);

    // il file è un svg
    Se(informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="svg")
    {
       // Se è così, eseguirne la compressione usando zopfli e brotli
       shell_exec("zopfli --gzip $percorsofile");
       shell_exec("brotli --best --output=$percorsofile.br $percorsofile");
    }

    // restituisci quello che abbiamo
    restituisce $metadati;
}

Nota che avrai bisogno di gzip_static e brotli_static abilitati nella tua configurazione di nginx.

Autocompila per una versione più recente

Ho scoperto che su Centos l'ultima versione di heif-enc è 1.7 che ha parecchi bug durante la creazione di avif. Quindi ho deciso di compilare il mio più recente (1.12) costruisci e usa quello invece. Farlo è stato un po' complicato in quanto richiedeva il codec aom come libreria condivisa. Per farlo, esegui i seguenti comandi bash. Assicurati di eseguirli come un utente normale, non come utente root. Nota anche che alcuni di questi comandi potrebbero non essere strettamente necessari, mi ci è voluto un po 'per farlo funzionare e ho appena preso nota di cosa ha funzionato - non sono affatto un esperto di Linux!

dnf install x265 x265-devel svt-av1
esporta CXXFLAGS="$CXXFLAGS -fPIC"
cd ~

git clone https://aomedia.googlesource.com/aom
mkdir -p aom_build
cd aom_build
cmake ~/aom -DBUILD_SHARED_LIBS=true
rendere
sudo make install
cp ./libaom.so.3 /usr/bin/local/libaom.so.3

cd ~
esporta PKG_CONFIG_PATH=~/aom_build/
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/aom_build/
esporta LD_LIBRARY_PATH

git clone --recurse-submodules --recursive https://github.com/strukturag/libheif.git
cd libheif
./autogen.sh
./configurare
rendere
sudo make install

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin/
esporta LD_LIBRARY_PATH

Una volta che l'hai fatto, assicurati che funzioni eseguendo php -a ed eseguendo il seguente comando

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

Dovresti ottenere un output completo, non solo un 1 errore di linea. Supponendo che funzioni bene, puoi modificare il tuo functions.php in modo che ciascuno dei riferimenti shell-exec punti a /usr/local/bin/heif-enc invece che solo a heif-enc

/*****************************\
* Converti png e jpg in avif *
\*****************************/
add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
funzione jps_compress_img( $metadati, $id_allegato )
{
   // ottieni il percorso del file da id
   $filepath= get_attached_file($id_allegato);

   // il file è un png o jpeg
   Se(informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="jpg" || informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="jpeg" || informazioni sul percorso($percorso del file, PATHINFO_EXTENSION)=="png")
   {
      // Se è così, esegui la compressione del file principale su avif
      shell_exec("/usr/local/bin/heif-enc $percorsofile -o $percorsofile.avif -q 50 -UN");
      $parti = preg_split('~/(?=[^/]*$)~', $percorso del file);

      // Quindi esegui la compressione delle miniature su avif
      $thumbpaths = $metadati['taglie'];
      per ciascuno ($thumbpaths come $key => $pollice)
      {
          $thumbpath= $thumb['file'];
          $thumbfullpath= $parts[0] . "/" . $thumbpath;
          shell_exec("/usr/local/bin/heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -UN");
      }
   }
   // restituisci quello che abbiamo
   restituisce $metadati;
}

Leave a Reply