timnarr/kirby-imagex

为 Kirby CMS 生成现代图片 – 此插件帮助您在 Kirby 中协调现代、响应式且性能优异的图片。

资助包维护!
www.buymeacoffee.com/tim.n

安装量: 1,275

依赖关系: 1

建议者: 0

安全性: 0

星星: 60

关注者: 3

分支: 0

公开问题: 1

类型:kirby-plugin

0.1.3 2024-09-02 12:22 UTC

This package is auto-updated.

Last update: 2024-09-02 12:27:25 UTC


README

Kirby Imagex Banner

Kirby Imagex

为 Kirby CMS 生成现代图片 – 此插件帮助您在 Kirby 中协调现代、响应式且性能优异的图片。

特性

  • 🌠 动态生成艺术指导或基于媒体条件的图片 srcset。
  • 📐 无需定义新的 srcset 预置即可轻松更改长宽比。
  • 😴 支持原生的懒加载,并且可以自定义 JavaScript 懒加载库。
  • 🚀 利用 Priority Hints 提高您的关键 LCP(最大内容绘制)图片的性能。
  • ⚡️ 支持多种现代图片格式,如 avifwebp
  • 🧩 可轻松集成到现有块/项目中。
  • 🪄 仅使用 Kirby 的核心功能处理图片。

入门指南

四步让 Imagex 运行起来

  1. 通过 Composer 安装
  2. 设置 Imagex 全局插件配置
  3. 调整 Kirby 的缩略图配置并添加 srcset 预置
  4. 在配置并传递选项到 Imagex 片段的地方添加片段

不同配置和 HTML 输出的示例

您可以在 examples.md 中找到所有示例。

通过 Composer 安装

composer require timnarr/kirby-imagex

全局配置

在您的 config.php 文件中配置全局设置

return [
  'timnarr.imagex' => [
    'cache' => true,
    'customLazyloading' => false,
    'formats' => ['avif', 'webp'],
    'includeInitialFormat' => false,
    'noSrcsetInImg' => false,
    'relativeUrls' => false,
  ],
];

调整 Kirby 的缩略图配置并添加 srcset 预置

srcset 配置仍然设置为从您所知的 Kirby 中设置,如此处所述

设置您的 srcset 预置,例如 my-srcset,并在此处定义宽度和其他配置。我在设置中省略了 height 并仅定义了 width。这使得处理图片变得更容易和更可预测,因为它允许您快速轻松地更改图片组件的比率或添加新的比率,而无需为您配置创建新的 srcset 预置。此第一个 srcset 预置用于 jpegpng 图片。

// config.php
'thumbs' => [
  'srcsets' => [
    'my-srcset' => [
      '400w'  => ['width' =>  400, 'crop' => true, 'quality' => 80],
      '800w'  => ['width' =>  800, 'crop' => true, 'quality' => 80],
      '1200w' => ['width' => 1200, 'crop' => true, 'quality' => 80],
    ],
    // other srcset definitions

如果您使用 avif 和/或 webp,则必须为这些格式分别设置单独的 srcset 预置。复制预置,并在名称后追加 -{format},然后为此预置设置 format 和其他选项。这是必要的,以便完全控制并定义每个现代格式的不同质量值或其他选项。

对于现代格式的质量设置不应简单地从初始预置中获取。要真正从现代格式的小型文件中受益,您应略微调整您的质量设置。我的经验法则是从 jpeg/png 质量中减去 5 以获得 webp,并从 avif 中减去 15。这里有一篇很好的 文章,但我也注意到这并不完全适用于 Kirby 中的图片。

// config.php
'thumbs' => [
  'srcsets' => [
    'my-srcset' => [ // preset for jpeg and png
      '400w'  => ['width' =>  400, 'crop' => true, 'quality' => 80],
      '800w'  => ['width' =>  800, 'crop' => true, 'quality' => 80],
      '1200w' => ['width' => 1200, 'crop' => true, 'quality' => 80],
    ],
    'my-srcset-webp' => [ // preset for webp
      '400w'  => ['width' =>  400, 'crop' => true, 'quality' => 75, 'format' => 'webp', 'sharpen' => 10],
      '800w'  => ['width' =>  800, 'crop' => true, 'quality' => 75, 'format' => 'webp', 'sharpen' => 10],
      '1200w' => ['width' => 1200, 'crop' => true, 'quality' => 75, 'format' => 'webp', 'sharpen' => 10],
    ],
    'my-srcset-avif' => [ // preset for avif
      '400w'  => ['width' =>  400, 'crop' => true, 'quality' => 65, 'format' => 'avif', 'sharpen' => 25],
      '800w'  => ['width' =>  800, 'crop' => true, 'quality' => 65, 'format' => 'avif', 'sharpen' => 25],
      '1200w' => ['width' => 1200, 'crop' => true, 'quality' => 65, 'format' => 'avif', 'sharpen' => 25],
    ],
    // other srcset definitions

片段配置和使用

如下所示,将您的图片文件对象和其他选项传递到 Imagex 片段中

// Define your options and pass them to the `imagex` snippet
<?php
$options = [
  'image' => $image->toFile(),
  'imgAttributes' => [
    'shared' => [
      'class' => 'my-image',
      'decoding' => 'async',
      'style' => ['background: red;'],
      'sizes' => '100vw',
    ],
  ],
  'ratio' => '16/9',
  'srcsetName' => 'my-srcset',
  'critical' => false,
];
?>

<?php snippet('imagex-picture', $options) ?>

Imagex 输出一个包含多个 <source> 元素和一个 <img> 元素的 <picture> 元素。如果您需要额外的 HTML,可以相应地包装 Imagex 片段。根据需要不同地处理 svggif 文件!

<?php

$options = [
  'image' => $image->toFile(),
  // ... other imagex options
];

?>

<figure>
  <?php if ($image->extension() === 'svg' || $image->extension() === 'gif'): ?>
    <?php snippet('svg-gif-image') ?> // handle svg and gif files differently
  <?php else: ?>
    <?php snippet('imagex-picture', $options) ?>
  <?php endif; ?>
  <figcaption>Lorem ipsum</figcaption>
</figure>

片段选项

您可以从许多选项中选择来自定义您的图像并将它们传递给 Imagex 片段。一开始可能看起来很复杂,但实际上它非常灵活,实际上只需 image 是必需的,其他所有内容都可以省略,同时 Imagex 提供了一些合理的默认值。

对于图像元素中的每个 HTML 元素,您可以添加属性、CSS 类、内联样式、数据属性等。您只需将这些属性添加到这三个属性类别之一,我将它们称为“加载模式”:sharedeagerlazyshared 模式用于始终存在的属性,无论图像的加载模式如何。如果您有一些属性仅在 eagerlazy 加载模式下使用,可以将它们添加到其中之一。Imagex 将自动合并 shared 属性与当前加载模式的属性。不适用的加载模式的属性将没有任何效果。

<?php
$options = [
  'image' => $image,
  'pictureAttributes' => [
    'shared' => [
      'class' => 'my-picture-class',
      'data-attr' => 'my-picture-attribute'
    ],
    'eager' => [
      // extend `shared` attributes in eager loading mode
      'class' => 'my-picture-class--eager'
    ],
    'lazy' => [
      // extend `shared` attributes in lazy loading mode
      'class' => 'my-picture-class--lazy js-image'
    ],
  ],
  'imgAttributes' => [
    'shared' => [
      'class' => [
        'my-image-class',
        $setThisClassWhenTrue ? 'optional-class' : null
      ],
      'alt' => $image->alt(),
      'style' => ['background-color: red;', 'object-fit: cover;', 'object-position: ' . $image->focus() . ';'],
      'data-attr' => 'my-img-attribute',
      'sizes' => '760px',
    ],
    'eager' => [
      // extend `shared` attributes in eager loading mode
    ],
    'lazy' => [
      // extend `shared` attributes in lazy loading mode
    ],
    // Do not add `src`, `srcset` or `loading` or their equivalents for lazy loading (like `data-src`) here.
    // These attributes are handled automatically by Imagex and adding them here will throw an exception.
  ],
  'srcsetName' => 'my-srcset',
  'critical' => $isCritical ?? false,
  'ratio' => '1/1',
  'sourcesArtDirected' => [
    ['ratio' => '21/9', 'media' => '(min-width: 1200px)']
    ['media' => '(min-width: 820px)', 'image' => $artDirectedImage]
    ['ratio' => '16/9', 'media' => '(prefers-color-scheme: dark)', 'image' => $darkModeImage]
    ['ratio' => '21/9', 'media' => '(orientation: landscape)', 'attributes' => ['shared' => ['attribute' => 'value'], 'eager' => [], 'lazy' => []]]
  ],
];

// Pass your options to the Imagex snippet
<?php snippet('imagex-picture', $options) ?>

缓存

Imagex 将对每个图像进行一些简单的计算,例如根据给定的宽度和比例计算高度。基本上,Imagex 从配置文件中获取 srcset 定义,计算并设置高度,然后输出最终配置。结果将缓存在您使用相同的 srcset-preset 和比例组合为其他图像时,以减少不必要的计算。

关键图像的性能改进

Imagex 提供了像优先级提示这样的功能,以改善关键图像的加载时间。

优先级提示

Imagex 将优先级提示 fetchpriority="high" 设置为关键图像,以使浏览器尽早加载它。如果将 'critical' => true 传递给 Imagex 片段,则 Imagex 默认设置此提示。有关 fetchpriority 的更多信息

为什么顺序很重要?

格式顺序和媒体属性

<picture> 元素中 <source> 元素的顺序至关重要,因为浏览器根据支持的格式和媒体条件选择第一个匹配的源。现代格式如 avif 应该首先列出,然后回退到如 webpjpeg 这样的格式。Imagex 将遵循配置中定义的格式顺序,您应该从最现代的格式到最不现代的格式:'formats' => ['avif', 'webp']

media 属性对于响应式设计或艺术指导图像也很重要。使用媒体属性,您可以指定每个源应使用的条件。如果您想在特定的媒体条件下切换比例或完整的图像,这很重要。您必须注意您传递给 Imagex 片段的插件选项中 sources 数组的顺序。Imagex 将为每个格式创建所有定义的源。

动态格式大小处理

在某些情况下,avif 文件可能比 webp 文件大,从而导致向用户发送更多的 HTML 和更大的文件。如果将 formatSizeHandling 设置为 true,则此选项启用指定图像格式之间的动态尺寸比较。比较基于您配置的格式数组中格式的列表顺序。使用默认的 formats 数组,此选项将检查 avif 是否小于 webp,并且只有当它更小的时候才输出或创建 avif 文件。因此,您的格式数组顺序对此功能很重要。当前的大小比较非常基础,Imagex 仅生成传递的 srcset 预设的中间项,并比较其大小与下一个格式。如果较新的格式文件更大,则不会生成 srcset 预设的其余部分,并且在 HTML 输出中也会省略。

🚧 此功能目前非常基础。 它仅生成给定 srcset 预设的中间项/宽度,并检查文件大小是否小于下一个较旧的格式。目前,这仅针对初始图像执行,而不针对艺术指导源图像。

路线图/想法

  • 为 Imagex 类添加测试
  • 使用预加载资源提示?!请参阅 功能分支
  • 改进使用 formatSizeHandling 时确定最小格式的准确性
  • 改进与艺术指导图像结合使用的 formatSizeHandling

许可证

MIT 许可证 版权 © 2024-至今 Tim Narr