Passei muito tempo otimizando o desempenho deste site, e, como parte do trabalho contínuo, monito novas tecnologias que podem ajudar a melhorar a velocidade para os visitantes. Eu acompanho a adoção de formatos de imagem de próxima geração há um tempo e com o suporte de navegadores da web agora bastante difundido, era hora de descobrir como fazer uso desses novos formatos no wordpress.
Existem várias etapas necessárias que dividi nos títulos abaixo
Ativar suporte em nginx
A primeira etapa é habilitar seu servidor web (no meu caso nginx) para reconhecer os tipos MIME dos novos formatos. Para fazer isso, você precisa editar mime.types, que provavelmente pode ser encontrado em /etc/nginx/mime.types. Eu adicionei a seguinte seção
1 2 3 4 5 6 7 | image/heic heic; image/heif heif; image/heic-sequence heics; image/heif-sequence heifs; image/avif avif; image/avif-sequence avis; image/jxl jxl; |
Servir arquivos automaticamente onde eles estão disponíveis
O próximo passo é dizer ao nginx para servir arquivos automaticamente sempre que eles existirem (e voltar para formatos mais antigos, onde um novo arquivo de formato não existe)
Para fazer isso, primeiro edite o arquivo de configuração principal do nginx (geralmente /etc/nginx/nginx.conf) e adicione a seguinte seção dentro do http{} seção da configuração
1 2 3 4 5 6 7 | map $http_accept $img_ext { ~image/jxl ‘.jxl’; ~image/avif ‘.avif’; ~image/webp ‘.webp’; default ”; } |
Observe que estou apenas tentando servir jxl (JPEG-XL) ou arquivos avif, você poderia adicionar mais opções (em ordem de preferência!) se você desejar.
Próximo, você precisa adicionar o seguinte no servidor{} seção da configuração do nginx (que pode estar no arquivo de configuração principal ou em um arquivo de configuração separado, dependendo de como você configurou sua estrutura de configuração do nginx)
1 2 3 4 5 | location ~* ^.+\.(png|jpg|jpeg)$ { add_header Vary Accept; try_files $uri$img_ext $uri =404; } |
Agora o nginx irá procurar por image.jpg.jxl e então image.jpg.avif e então image.jpg.webp e finalmente image.jpg quando for solicitado por image.jpg por qualquer navegador que suporte os formatos mais novos. Em seguida, precisamos habilitá-los no wordpress
habilitar formatos de próxima geração no wordpress
Adicione o seguinte código ao seu functions.php (o ideal é fazer isso em um tema filho para que, ao atualizar seu tema, suas alterações não sejam substituídas)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /***************************************************\ * Enable SVG support and other modern image formats * \***************************************************/ function cc_mime_types( $mimes ) { $mimes[‘svg’] = ‘image/svg+xml’; $mimes[‘webp’] = ‘image/webp’; $mimes[‘heic’] = ‘image/heic’; $mimes[‘heif’] = ‘image/heif’; $mimes[‘heics’] = ‘image/heic-sequence’; $mimes[‘heifs’] = ‘image/heif-sequence’; $mimes[‘avif’] = ‘image/avif’; $mimes[‘avis’] = ‘image/avif-sequence’; $mimes[‘jxl’] = ‘image/jxl’; return $mimes; } add_filter( ‘upload_mimes’, ‘cc_mime_types’ ); |
Observe que também habilitei o suporte para SVG imagens ao mesmo tempo
Agora você pode fazer upload de imagens no formato de próxima geração e usá-las diretamente no Wordpress se quiser, mas eu não recomendo isso porque muitos navegadores mais antigos ainda não os suportam - e nós já configuramos o nginx para atendê-los de forma inteligente, então devemos fazer uso disso. O que queremos fazer é gerar automaticamente os novos formatos quando carregamos as imagens (já existem plug-ins que fazem isso para webp, mas nada que faça isso por jxl ou avif ainda).
Instale libheif
Esta etapa requer acesso à linha de comando do seu host, o que é direto se você executar um VPS, mas pode não ser tão simples se você estiver em uma hospedagem compartilhada, caso em que pode ser necessário pedir suporte ao seu host
Execute os seguintes comandos bash (estes são selecionados para Centos 8, outras distribuições podem ser um pouco diferentes)
1 2 | 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 |
Adicione uma função personalizada ao wordpress functions.php para compactar todas as imagens enviadas (e suas miniaturas) para o formato avif
Como com a etapa anterior de functions.php, recomendo adicionar isso em um tema filho
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /*****************************\ * Convert png and jpg to avif * \*****************************/ add_filter( ‘wp_generate_attachment_metadata’, ‘jps_compress_img’, 10, 2 ); function jps_compress_img( $metadata, $attachment_id ) { // get filepath from id $filepath= get_attached_file($attachment_id); // is the file a png or jpeg if(pathinfo($filepath, PATHINFO_EXTENSION)==“jpg” || pathinfo($filepath, PATHINFO_EXTENSION)==“jpeg” || pathinfo($filepath, PATHINFO_EXTENSION)==“png”) { // If so, run compression of the main file to avif shell_exec(“heif-enc $filepath ‑o $filepath.avif ‑q 50 ‑A”); $parts = preg_split(‘~/(?=[^/]*$)~’, $filepath); // Then run compression of the thumbnails to avif $thumbpaths = $metadata[‘sizes’]; foreach ($thumbpaths as $key => $thumb) { $thumbpath= $thumb[‘file’]; $thumbfullpath= $parts[0] . “/” . $thumbpath; shell_exec(“heif-enc $thumbfullpath ‑o $thumbfullpath.avif ‑q 50 ‑A”); } } // give back what we got return $metadata; } //dont forget to delete the avifs if the attachments are deleted function jps_delete_avif($attachment_id) { $all_images= get_intermediate_image_sizes($attachment_id); foreach($all_images as $each_img) { $each_img_det= wp_get_attachment_image_src($attach_id,$each_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’ ); |
No momento, é isso - todas as imagens que você enviar serão convertidas em cópias avif (com os originais retidos). Você pode regenerar todas as suas imagens para criar os arquivos avif usando um plugin. Observação - ainda não configurei JPEG-A compressão XL como suporte ainda não está disponível nos navegadores convencionais (embora esteja em navegadores de pré-lançamento, por isso estará disponível em breve).
Embora eu esteja cobrindo formatos de próxima geração e otimização, tenho uma dica final - para compactar SVG imagens com gzip (ou ainda melhor zopfli e brotli). Para fazer isso, é necessária outra função personalizada ...
Bônus: SVG compressão
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /*************************************************\ * Compress SVG images more with brotli and zopfli * \*************************************************/ add_filter( ‘wp_generate_attachment_metadata’, ‘jps_compress_vectors’, 10, 2 ); function jps_compress_vectors( $metadata, $attachment_id ) { // get filepath from id $filepath= get_attached_file($attachment_id); // is the file an svg if(pathinfo($filepath, PATHINFO_EXTENSION)==“svg”) { // If so, run compression of it using zopfli and brotli shell_exec(“zopfli –gzip $filepath”); shell_exec(“brotli –best –output=$filepath.br $filepath”); } // give back what we got return $metadata; } |
Observe que você precisará de gzip_static e brotli_static habilitados em sua configuração nginx.
Auto-compilar para uma versão mais recente
Descobri que no Centos a versão mais recente do heif-enc é 1.7 que tem alguns bugs ao criar avifs. Então optei por compilar meu próprio (1.12) construir e usar isso. Fazer isso foi um pouco complicado, pois exigia o codec aom como uma biblioteca compartilhada. Para fazer isso, execute os seguintes comandos bash. Certifique-se de executá-los como um usuário normal, não como o usuário root. Observe também que alguns desses comandos podem não ser estritamente necessários, demorei um pouco para fazê-lo funcionar e apenas anotei o que funcionou - não sou de forma alguma um especialista em Linux!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | dnf install x265 x265-devel svt-av1 export CXXFLAGS=”$CXXFLAGS ‑fPIC” cd ~ git clone https://aomedia.googlesource.com/aom mkdir -p aom_build cd aom_build cmake ~/aom -DBUILD_SHARED_LIBS=true make sudo make install 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/ export LD_LIBRARY_PATH git clone –recurse-submodules –recursive https://github.com/strukturag/libheif.git cd libheif ./autogen.sh ./configure make sudo make install LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/bin/ export LD_LIBRARY_PATH |
Depois de fazer isso, certifique-se de que funciona executando php -a
e executando o seguinte comando
1 | shell_exec(“/usr/local/bin/heif-enc ‑A”); |
Você deve obter uma saída completa, não apenas um 1 erro de linha. Assumindo que funcione bem, você pode modificar seu functions.php para que cada uma das referências do shell-exec aponte para / usr / local / bin / heif-enc em vez de apenas heif-enc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /*****************************\ * Convert png and jpg to avif * \*****************************/ add_filter( ‘wp_generate_attachment_metadata’, ‘jps_compress_img’, 10, 2 ); function jps_compress_img( $metadata, $attachment_id ) { // get filepath from id $filepath= get_attached_file($attachment_id); // is the file a png or jpeg if(pathinfo($filepath, PATHINFO_EXTENSION)==“jpg” || pathinfo($filepath, PATHINFO_EXTENSION)==“jpeg” || pathinfo($filepath, PATHINFO_EXTENSION)==“png”) { // If so, run compression of the main file to avif shell_exec(“/usr/local/bin/heif-enc $filepath ‑o $filepath.avif ‑q 50 ‑A”); $parts = preg_split(‘~/(?=[^/]*$)~’, $filepath); // Then run compression of the thumbnails to avif $thumbpaths = $metadata[‘sizes’]; foreach ($thumbpaths as $key => $thumb) { $thumbpath= $thumb[‘file’]; $thumbfullpath= $parts[0] . “/” . $thumbpath; shell_exec(“/usr/local/bin/heif-enc $thumbfullpath ‑o $thumbfullpath.avif ‑q 50 ‑A”); } } // give back what we got return $metadata; } |
O que você acha? Deixe-nos cair um comentário abaixo! Se você deseja se inscrever, use o link de inscrição no menu no canto superior direito. Você também pode compartilhar isso com seus amigos usando os links sociais abaixo. Felicidades.
Deixe uma resposta