0WordPress的标志使用 wordpress 自动生成和提供 avif 图像

我花了很多时间优化这个网站的性能, 作为正在进行的工作的一部分,我监控可以帮助提高访问速度的新技术. 我一直在跟踪下一代图像格式的采用情况,现在网络浏览器的支持相当普遍,是时候弄清楚如何在 wordpress 中使用这些新格式了.

需要多个步骤,我已将其分解为下面的标题

在 nginx 中启用支持

第一步是启用您的网络服务器 (就我而言,nginx) 识别新格式的 mime 类型. 为此,您需要编辑可能在 /etc/nginx/mime.types 中找到的 mime.types. 我添加了以下部分

/内容违反规则违反规则;
图像/母牛;
图像/heic-sequence heic;
图像/ heif 序列 heifs;
图像/avif avif;
图像/avif-序列审查;
图像 / jxl jxl;

在文件可用时自动提供文件

下一步是告诉 nginx 在文件存在时自动提供文件 (并退回到不存在新格式文件的旧格式)
为此,首先编辑主 nginx 配置文件 (通常 /etc/nginx/nginx.conf) 并在 http 中添加以下部分{} 配置部分

映射 $http_accept $img_ext
{
   ~ 图像 / jxl '.jxl';
   ~图像/avif '.avif';
   〜图像/ webp '.webp';
   默认      '';
}

请注意,我只是想为 jxl 服务 (JPEG-加大码) 或avif文件, 你可以添加更多选项 (按优先顺序!) 如果你希望.
下一个, 您需要在服务器下添加以下内容{} nginx 配置部分 (它可能位于主配置文件中,也可能位于单独的配置文件中,具体取决于您如何设置 nginx 配置结构)

位置 ~* ^.+.(PNG|JPG|JPEG)$
{
   add_header 变化 接受;
   try_files $uri$img_ext $uri =404;
}

现在,当任何支持较新格式的浏览器要求提供 image.jpg 时,nginx 将查找 image.jpg.jxl 然后是 image.jpg.avif 然后是 image.jpg.webp 最后是 image.jpg. 接下来我们需要在wordpress中启用它们

在 wordpress 中启用下一代格式

将以下代码添加到您的functions.php (理想情况下,在子主题中执行此操作,以便在更新主题时不会覆盖更改)

/***************************************************\
* 启用 SVG的 支持和其他现代图像格式 *
\***************************************************/
函数 cc_mime_types( $哑剧 )
{
   $哑剧['svg'] = '图像/svg+xml';
   $哑剧['webp'] = '图像/网络';
   $哑剧[“违反”] = "图像 / 不熟练的 ';
   $哑剧['heif'] = '图像/heif';
   $哑剧['十六进制'] = "图像/违反规则序列';
   $哑剧['小牛'] = '图像/heif-序列';
   $哑剧['avif'] = '图像/avif';
   $哑剧['注意'] = '图像/avif 序列';
   $哑剧['jxl'] ='图像/jxl';
   返回 $mimes;
}
的add_filter( '上传_哑剧', 'cc_mime_types' );

请注意,我还启用了对 SVG的 同时图像

现在,您实际上可以上传下一代格式的图像,并在需要时直接在 wordpress 中使用它们, 但我不建议这样做,因为许多旧浏览器还不支持它们——而且我们已经设置了 nginx 来智能地为它们提供服务,所以我们应该利用它. 我们要做的是在我们上传图片的时候自动生成新的格式 (已经有插件可以为 webp 执行此操作, 但还没有对 jxl 或 avif 起作用).

安装 libheif

此步骤确实需要访问您的网络主机的命令行, 如果你运行一个,这是直接的 VPS, 但如果您使用的是共享主机,则可能不那么简单,在这种情况下,您可能需要向主机寻求支持
运行以下 bash 命令 (这些被选中用于 Centos下 8, 其他发行版可能略有不同)

dnf -y 安装 --nogpgcheck https://下载1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm https://下载1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm
dnf -y 安装 libheif

在wordpressfunctions.php中添加自定义函数来压缩所有上传的图片 (和他们的缩略图) 转avif格式

与之前的 functions.php 步骤一样,我建议将其添加到子主题中

/*****************************\
* 将 png 和 jpg 转换为 avif *
\*****************************/
的add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
函数 jps_compress_img( $元数据, $附件 ID )
{
   // 从 id 获取文件路径
   $filepath= get_attached_file($附件 ID);

   // 文件是 png 还是 jpeg
   如果(路径信息($文件路径, PATHINFO_EXTENSION)=="JPG" || 路径信息($文件路径, PATHINFO_EXTENSION)=="JPEG" || 路径信息($文件路径, PATHINFO_EXTENSION)=="PNG")
   {
      // 如果是这样的话, 将主文件压缩到 avif
      shell_exec("heif-enc $filepath -o $filepath.avif -q 50 -一");
      $零件 = preg_split('~/(?=[^/]*$)~', $文件路径);

      // 然后将缩略图压缩到avif
      $thumbpaths = $metadata['尺寸'];
      的foreach ($拇指路径为 $key => $拇指)
      {
          $拇指路径= $thumb['文件'];
          $拇指全路径= $parts[0] . "/" . $拇指路径;
          shell_exec("heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -一");
      }
   }
   // 回馈我们所得到的
   返回 $metadata;
}

//如果附件被删除,不要忘记删除avifs
函数 jps_delete_avif($附件 ID)
{
   $all_images= get_intermediate_image_sizes($附件 ID);
   的foreach($all_images 作为 $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],链球菌($each_img_det[0],"/上传/")).'.avif';
      shell_exec("rm -f $each_img_path");
   }
}
ADD_ACTION( '删除附件', 'jps_delete_avif' );

目前就是这样 - 您上传的所有图像都将转换为 avif 副本 (保留原件). 您可以使用插件重新生成所有图像以创建 avif 文件. 注意——我还没有设置 JPEG-主流浏览器尚不支持 XL 压缩作为对它的支持 (虽然它在预发布浏览器中,所以它很快就会推出).

虽然我正在讨论下一代格式和优化,但我还有一个最后的技巧——压缩 SVG的 带有 gzip 的图像 (甚至更好的 zopfli 和 brotli). 要做到这一点,需要另一个自定义函数……

奖金: SVG的 压缩

/*************************************************\
* 压缩 SVG的 使用 brotli 和 zopfli 获取更多图像 *
\*************************************************/
的add_filter( 'wp_generate_attachment_metadata', 'jps_compress_vectors', 10, 2 );
函数 jps_compress_vectors( $元数据, $附件 ID )
{
    // 从 id 获取文件路径
    $filepath= get_attached_file($附件 ID);

    // 该文件是 svg
    如果(路径信息($文件路径, PATHINFO_EXTENSION)=="SVG")
    {
       // 如果是这样的话, 使用 zopfli 和 brotli 对其进行压缩
       shell_exec("zopfli --gzip $文件路径");
       shell_exec("brotli --best --output=$filepath.br $filepath");
    }

    // 回馈我们所得到的
    返回 $metadata;
}

请注意,您需要在 nginx 配置中启用 gzip_static 和 brotli_static.

为新版本自行编译

我发现在 Centos 上最新版本的 heif-enc 是 1.7 创建avifs时有很多错误. 所以我选择编译我自己的更新 (1.12) 构建并使用它. 这样做有点复杂,因为它需要 aom 编解码器作为共享库. 为此,请运行以下 bash 命令. 确保以普通用户身份运行它们, 不是 root 用户. 另请注意,其中一些命令可能不是严格需要的, 我花了一段时间才让它工作,我只是记下了有效的东西——我绝不是 Linux 专家!

dnf 安装 x265 x265-devel svt-av1
出口 CXXFLAGS="$CXXFLAGS -fPIC"
光盘~

git 克隆 https://aomedia.googlesource.com/aom
mkdir -p aom_build
cd aom_build
cmake ~/aom -DBUILD_SHARED_LIBS=true
制作
须藤制作安装
cp ./libaom.so.3 /usr/bin/local/libaom.so.3

光盘~
导出 PKG_CONFIG_PATH=~/aom_build/
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/aom_build/
导出 LD_LIBRARY_PATH

git clone --recurse-submodules --recursive https://github.com/strukturag/libheif.git
光盘库
./autogen.sh
。/配置
制作
须藤制作安装

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/用户/本地/bin/
导出 LD_LIBRARY_PATH

一旦你这样做了, 通过运行确保它工作 php -a 并运行以下命令

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

你应该得到一个完整的输出, 不只是一个 1 线路错误. 假设工作正常,您可以修改您的functions.php,以便每个shell-exec引用都指向/usr/local/bin/heif-enc,而不仅仅是heif-enc

/*****************************\
* 将 png 和 jpg 转换为 avif *
\*****************************/
的add_filter( 'wp_generate_attachment_metadata', 'jps_compress_img', 10, 2 );
函数 jps_compress_img( $元数据, $附件 ID )
{
   // 从 id 获取文件路径
   $filepath= get_attached_file($附件 ID);

   // 文件是 png 还是 jpeg
   如果(路径信息($文件路径, PATHINFO_EXTENSION)=="JPG" || 路径信息($文件路径, PATHINFO_EXTENSION)=="JPEG" || 路径信息($文件路径, PATHINFO_EXTENSION)=="PNG")
   {
      // 如果是这样的话, 将主文件压缩到 avif
      shell_exec("/usr/local/bin/heif-enc $filepath -o $filepath.avif -q 50 -一");
      $零件 = preg_split('~/(?=[^/]*$)~', $文件路径);

      // 然后将缩略图压缩到avif
      $thumbpaths = $metadata['尺寸'];
      的foreach ($拇指路径为 $key => $拇指)
      {
          $拇指路径= $thumb['文件'];
          $拇指全路径= $parts[0] . "/" . $拇指路径;
          shell_exec("/usr/local/bin/heif-enc $thumbfullpath -o $thumbfullpath.avif -q 50 -一");
      }
   }
   // 回馈我们所得到的
   返回 $metadata;
}

Leave a Reply