网站生成器、框架和 CMS

了解如何通过 CMS(例如 WordPress)和其他网站生成器更轻松地使用自适应图片。

虽然与手动保存每张图片的替代剪辑并通过 Squoosh.app 等工具手动对其进行优化相比,这种方法确实有待改进,但在开发过程中,自动压缩图片存在一些限制。首先,您可能无法始终完全控制整个网站使用的图片 - 网络上大多数面向用户的图片更侧重于内容,而不是由用户或编辑者上传的开发问题,而不是与 JavaScript 和样式表等开发资源一起存储在代码库中。

这通常需要多个图片管理流程:一个是开发级任务,涉及构建和维护网站时使用的图片资源(背景、图标、徽标等),另一个涉及通过网站生成的图片资源,例如编辑团队在帖子中嵌入的照片或用户上传的头像。虽然上下文可能不同,但最终目标都是相同的:根据开发团队定义的设置自动编码和压缩。

幸运的是,您从本地开发工作流中了解的图片处理库可用于任意数量的上下文。虽然不可能没有放之四海而皆准的方法来处理自适应图片标记,但这些系统提供了合理的默认值、配置选项和 API 钩子来简化其实现。

静态网站生成器

与任务运行程序相比,静态网站生成器(例如 Jekyll 或 Eleventy 处理图片)在方式上有一些相似之处。要使用这些工具生成可供部署的网站,需要管理资源,包括 CSS 缩减、转译和捆绑 JavaScript。正如您所想,这意味着这些工具可让您使用已经了解的许多库,以相同的方式处理图片素材资源。

官方的 Eleventy 图片插件使用 Sharp 实现调整大小、生成多种来源大小、重新编码和压缩,就像您在这里学到的一些任务一样。

与任务运行程序不同,静态网站生成器可以直接深入了解这些库的配置和使用情况,以及为生产网站生成的标记,这意味着它可以更好地自动处理我们的自适应图片标记。例如,当作为用于显示图片的短代码的一部分被调用时,此插件会根据传递给 Sharp 的配置选项输出 HTML。


const Image = require("@11ty/eleventy-img");
module.exports = function(eleventyConfig) {

async function imageShortcode(src, alt, sizes="100vw") {
  let metadata = await Image(src, {
  formats: ["avif", "webp", "jpeg"],
  widths: [1000, 800, 400],
  outputDir: "_dist/img/",
  filenameFormat: function( id, src, width, format, options ) {
      const ext = path.extname( src ),
        name = path.basename( src, ext );

      return `${name}-${width}.${format}`
  }
  });

  let imageAttributes = {
  alt,
  sizes,
  loading: "lazy"
  };

  return Image.generateHTML(metadata, imageAttributes);
}

eleventyConfig.addAsyncShortcode("respimg", imageShortcode);
};

然后,便可使用此短代码代替默认的图片语法:

{‌% respimg "img/butterfly.jpg", "Alt attribute.", "(min-width: 30em) 800px, 80vw" %}

如果配置为输出多种编码,如上所述,生成的标记将是一个 <picture> 元素,其中包含相应的 <source> 元素、type 属性和 srcset 属性(已完全填充了生成的候选尺寸列表)。

<picture><source type="image/avif" srcset="/img/butterfly-400.avif 400w, /img/butterfly-800.avif 800w, /img/butterfly-1000.avif 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/webp" srcset="/img/butterfly-400.webp 400w, /img/butterfly-800.webp 800w, /img/butterfly-1000.webp 1000w" sizes="(min-width: 30em) 800px, 80vw"><source type="image/jpeg" srcset="/img/butterfly-400.jpeg 400w, /img/butterfly-800.jpeg 800w, /img/butterfly-1000.jpeg 1000w" sizes="(min-width: 30em) 800px, 80vw"><img alt="Alt attribute." loading="lazy" src="/img/butterfly-400.jpeg" width="1000" height="846"></picture>

当然,该插件无法generate可行的 sizes 属性,因为它无法知道图片在渲染布局中的最终尺寸和位置,但它确实能在生成标记时接受其中一个属性作为输入,这是 RespImageLint 的另一项工作。

框架

客户端渲染框架需要像 Webpack 一样的任务运行程序或捆绑器来编辑、编码和压缩图像资源。例如,Adaptive-loader 也会使用 Sharp 库重新保存图片素材资源。然后,您可以使用 import 将图片作为对象:

  import imageAVIF from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=avif';
  import imageWebP from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000&format=webp';
  import imageDefault from 'img/butterfly.jpg?sizes[]=400,sizes[]=800,sizes[]=1000';

然后,您可以通过 React 的图片组件等抽象概念使用这些导入的图片,或者直接填充自适应图片标记:

<picture>
  <source type='image/avif' srcSet={imageAVIF.srcSet} sizes='…' />
  <source type='image/webp' srcSet={imageWebp.srcSet} sizes='…' />
  <img
    src={imageDefault.src}
    srcSet={imageDefault.srcSet}
    width={imageDefault.width}
    height={imageDefault.height}
    sizes='…'
    loading="lazy"
  />

执行客户端渲染的框架非常适合 Lazysizessizes="auto",可为您提供几乎完全自动化的自适应图片。

内容管理系统

WordPress 是最早采用原生自适应图片标记的用户之一,自在 WordPress 4.4 中引入此 API 以来,该 API 已得到逐步改进,支持 WebP 并支持输出 MIME 类型。WordPress 核心的设计宗旨是使用 ImageMagick PHP 扩展程序(或者若没有该扩展程序,则使用 GD 库)。

通过 WordPress 管理界面上传图片后,系统会使用该来源图片在服务器上生成面向用户的文件,操作方式与在本地计算机上大致相同。默认情况下,WordPress 输出的任何图片都会带有一个根据主题中配置的图片大小生成的 srcset 属性。

可以为生成的图片配置的两个关键设置是压缩质量输出 MIME 类型

例如,如需将所有生成的图片的默认压缩质量设置为 70,请使用以下命令:

add_filter( 'wp_editor_set_quality', function() { return 70; } );

为了更好地进行压缩,请使用以下代码将上传的 JPEG 图片的输出格式切换为 WebP:

add_filter( 'image_editor_output_format', function( $mappings ) {
  $mappings[ 'image/jpeg' ] = 'image/webp';
    return $mappings;
} );

鉴于 WordPress 充分了解它基于上传的图片生成的所有备用剪切和编码,它可以提供 wp_get_attachment_image_srcset() 等辅助函数来检索图片附件的完整、生成 srcset 值。

您可能已经猜到,使用 sizes 属性有点麻烦。由于没有关于图片在布局中使用方式的任何信息,WordPress 目前默认使用 sizes 值,该值实际上是“此图片应占据可用视口的 100%,直至达到最大来源的固有尺寸”。这是一种可预测的默认指标,但并不适合任何实际应用。请务必使用 wp_calculate_image_sizes() 在模板中设置适合上下文的 sizes 属性。

当然,有数不清的 WordPress 插件致力于为开发团队和用户提高现代映像工作流的速度。 也许最令人兴奋的是,像 Jetpack 的 Site Accelerator(以前称为“ Photon”)之类的插件可以提供服务器端的编码协商,从而确保用户收到浏览器能够支持的最小、最高效的编码,而无需使用 <picture>type 标记模式。它使用图片内容分发网络实现这一点,图片内容分发网络是一种您可以独立于 CMS 的技术。

这同样适用于 Shopify 等托管 CMS 解决方案,但机制本身略有不同:用于生成备用图片来源和相应的 srcset 属性以及通过 <picture> 元素提供艺术指导的类似钩子。