acalvino4/craft-easy-image

以最少的配置实现最大化的图片优化

安装: 243

依赖: 1

建议者: 0

安全: 0

星星: 12

关注者: 1

分支: 3

开放问题: 3

类型:craft-plugin

2.0.1 2024-07-20 19:23 UTC

This package is auto-updated.

Last update: 2024-09-20 19:50:35 UTC


README

通过最少的代码实现最大化的图片优化。

License Build Status

Test Coverage Phpstan Level Easy Coding Standard

简介

实现最大优化图片的标记是 复杂的。你需要了解很多才能做对,即使你做到了,在整个团队中传播和执行这种知识,更不用说在没有错误的情况下实施它,都是一个挑战。你需要知道的一些事情包括

  • 我如何使用高度和宽度来避免布局移动,同时仍然允许通过CSS进行缩放?
  • srcset中的源顺序重要吗?
  • picture元素中源标签的顺序重要吗?
  • 我如何配置艺术指导的源?
  • 我应该使用宽度描述符还是'x'描述符?
  • 我如何指定回退图像格式?
  • 我如何让浏览器在加载之前或CSS加载之前知道我的图像将显示多宽?
  • jpg的MIME类型是什么?
  • sizes属性中媒体查询的顺序重要吗?
  • 哪些属性放在img标签上,哪些放在source标签上,哪些放在两者上?
  • 我如何在图像加载之前生成和包含模糊占位符?
  • 我如何将模糊占位符替换为实际图像(不使用JS)?

但是,如果你不必考虑所有这些,而是只通过指定你的资产、变换集名称以及你想要应用的任何HTML属性来获取正确的标记,会怎么样呢?

大多数图像优化插件需要太多的配置,或者不使用最新的最佳实践。如果你的变换服务支持avif,你就不必为每个变换指定它。通常你想要'覆盖'模式。变换集之间变化的主要事情是调整大小,所以我们只让你配置这一点(其他所有内容都是可选的,但仍然可能)。

此插件提供了优化(但可配置)的默认变换,并提供了twig函数来输出所有正确的picture标记,而无需您思考。

我们提供无压力的标记生成,

  • 默认为下一代图像格式(avif
  • 为旧浏览器加载适当的回退格式(webp -是的,webp即使在“旧”浏览器版本上也工作)
  • 设置高度和宽度以避免CLS
  • 根据视口和分辨率加载缩放图像
  • 处理艺术指导
  • 处理懒加载
  • 生成、加载和交换模糊占位符图像

所有这些

  • 现代、合理的默认设置
  • 灵活、有组织、可级联的配置

用法

config/easy-image.php中包含以下内容(请参阅插件src目录中的注释config.php

<?php

use acalvino4\easyimage\models\Settings;
use acalvino4\easyimage\models\TransformSet as TS;

return get_object_vars(new Settings(
  transformSets: [
    'hero' => new TS(
      widths: [2560, 1280],
      aspectRatio: 2 / 1,
    ),
    'hero-mobile' => new TS(
      widths: [640, 320],
      aspectRatio: 1 / 2,
    ),
    'thumbnail' => ...
    'catalog-item' => ...
  ],
));

然后,在需要英雄图像的地方,只需在您的twig标记中使用以下内容

{{ picture([entry.myImageField.one(), 'hero'], "mx-auto my-10 lg:my-20") }}

这将输出类似以下内容

<picture>
  <source
    type="image/avif"
    srcset="
      https://easyimage.local/transforms/_2560x1280_crop_center-center_none/example.avif 2560w,
      https://easyimage.local/transforms/_1280x640_crop_center-center_none/example.avif  1280w
    "
    height="144"
    width="288"
  />
  <img
    class="mb-10 mx-auto lg:-mb-10"
    src="https://easyimage.local/transforms/_2560x1280_crop_center-center_none/example.webp"
    srcset="
      https://easyimage.local/transforms/_2560x1280_crop_center-center_none/example.webp 2560w,
      https://easyimage.local/transforms/_1280x640_crop_center-center_none/example.webp  1280w
    "
    height="144"
    width="288"
    alt="example"
    loading="lazy"
  />
</picture>

需要注意的几点

  • 图像格式是avif(84%支持),回退到webp(98%支持)。
  • 假定懒加载(但可以通过以下解释的参数关闭)。
  • 类列表传递到img元素,无论使用哪个源都会应用。(其他属性也可以按照以下说明传递。)
  • 输出的高度和宽度与固有尺寸不匹配,因为当我们使用 srcset 时,并不只有一个固有尺寸。然而,这些数字确实与正确的宽高比相对应,这对于避免布局偏移(CLS)非常重要。

API

配置

配置通过 config/easy-image.php 设置。遵循上面的示例,或者查看 vendor/acalvino4/easy-image/src/config.php 以获取更详细的示例。

图片Twig函数

我们将展示函数签名,提供一些解释,然后是一些示例。

签名

/**
 * Picture
 *
 * @phpstan-type ImageData array{Asset, string, 2?: int}
 * @param ImageData|ImageData[] $images
 * @param mixed[]|string $attributes
 * @param boolean $eager
 * @return string
 */
public function picture(array $images, $attributes = [], $eager = false): string {}

解释

  • $images - 一个 ImageData 值,或者这些值的数组。每个 ImageData 值仅仅是一个包含
    • 资产、
    • 要使用的转换集名称(在配置中定义),
    • 图像应使用的最小宽度(用于艺术指导)。默认为0;如果你只有一个 ImageData,则不相关。
  • $attributes - 一个应用到此图片元素的html属性的哈希。支持与 \craft\helpers\Html::renderTagAttributes() 相同的属性定义。可以提供一个类名字符串,并将它作为这样的应用。
  • $eager - 此图像是否应被预先加载(通常)。默认为false,意味着此图像将进行懒加载。

示例

上述示例展示了基本用法

{{ picture([entry.myImageField.one(), 'hero'], 'mx-auto my-10 lg:my-20') }}

请注意,当 $attributes 参数是一个字符串时,它被解释为类名列表。

最复杂的示例可能看起来像这样

{{ picture(
  [
    [entry.myImageField.one(), 'hero', 768],
    [entry.myImageFieldAlt.one(), 'hero-mobile'],
  ], {
    class: 'mx-auto my-10 lg:my-20',
    data-something: 'custom stuff',
  }),
  true,
}}

此示例将在小屏幕上加载备用图像,使用 'hero-mobile' 转换集。在768px及以上的屏幕上,它将使用之前的相同图像和 'hero' 转换集。

在这两种情况下,生成的标记将包含 data-something 属性,并且将 进行懒加载。

大小

如果你使用此插件按照上述方式生成图像标记,你做得很好!但要真正优化,你应该将 sizes 属性传递给属性列表。默认情况下,浏览器将从你的 srcset 中选择与浏览器视口宽度匹配的宽度描述符。这是必要的,因为虽然CSS样式可能将图像宽度限制为两列布局的50%,或者一个平坦的50px,但在CSS加载之前,浏览器可能需要请求这些图像。如果你的图像是全宽的,那么你没问题,但很多时候,图像只占据视口的一小部分 - 例如,缩略图。

sizes 属性描述了图像将在html中直接显示的宽度,以便浏览器可以直接请求适当的图像。它通常应该与你的CSS样式相匹配,如下面的示例所示,但请记住,父容器也可能限制图像的宽度。请注意,浏览器将使用第一个匹配的媒体查询,所以最后列出更通用的案例。

sizes 示例

  {{ picture([entry.testAsset.one(), 'hero'], {
    class: "w-full sm:px-16 2xl:w-[640px]",
    sizes: "(min-width: 1536px) 640px, (min-width: 640px) calc(100vw - 128px), 100vw",
  } ) }}

  {{ picture([entry.testAsset.one(), 'hero'], {
    class: "w-full sm:w-[640px]",
    sizes: "(min-width: 640px) 640px, 100vw",
  } ) }}

占位符图像

此插件将在你的图像加载之前内联一个模糊版本的图像;你不需要做任何事情。它通过 Blur Hash 插件生成此图像,该插件已自动包含。默认情况下,该插件将生成最大方向为64px的占位符,其大小约为几kb。因为内联这个大小相当大,所以我推荐通过在 config/blur-hash.php 中包含以下内容来覆盖它:

<?php

return [
    'blurredMaxImageSize' => 8,
];

这通常会将大小减少到500字节以下(在我的测试中约为250字节),同时保留相当多的细节并避免像素化。你可以尝试调整它以找到你所需的数据URI大小和细节之间的平衡。

需要注意的另一件事是,这个依赖项的许可方式为“treeware”,这意味着当你在生产中使用它时,被要求捐赠树木。这可以是一次性捐赠,没有任何最低限额。

与其他图像优化/转换插件的用法和比较

请参阅附带文档。

要求

此插件需要Craft CMS 4.4.0或更高版本,以及PHP 8.0.2或更高版本。

警告 如果进行本地转换,需要ImageMagick 7以避免某些错误(例如,将具有透明背景的png转换为avif会导致背景变为纯黑色)。

ddev和默认的ubuntu apt包默认将安装ImageMagick 6。我不了解在ddev中升级版本的方法,但对于ubuntu,只需在服务器上以root身份运行以下脚本。

t=$(mktemp) && wget 'https://dist.1-2.dev/imei.sh' -qO "$t" && bash "$t" && rm "$t"
apt-get -qq install php-pear php-dev >/dev/null
pecl install imagick -q >/dev/null </dev/null
# insert your version of php below
systemctl restart php<version>-fpm.service -q

安装

您可以从插件商店或使用Composer安装此插件。

从插件商店

转到项目控制面板中的插件商店,搜索“Easy Image”,然后按“安装”。

使用Composer

打开您的终端,并运行以下命令

# go to the project directory
cd /path/to/my-project.test

# tell Composer to load the plugin
composer require acalvino4/craft-easy-image

# tell Craft to install the plugin
./craft plugin/install easy-image

路线图

  • 按图像转换覆盖
  • 资产的文件路径或URL
  • 在上传时转换/优化图像
  • 在图像加载后移除blurhash - 用于图像具有透明区域的情况