站点生成器、框架和 CMS

了解 WordPress 等 CMS 以及其他站点生成器如何让响应式图片的使用更加轻松。

虽然与手动保存每张图片的备用版本并通过 Squoosh.app 等工具手动优化相比,这无疑是一种进步,但将图片压缩自动化作为开发过程中的一个步骤也存在一些局限性。首先,您可能并不总是能够完全控制整个网站中使用的图片 - Web 上大多数面向用户的图片更多的是内容问题,而不是开发问题,由用户或编辑上传,而不是与 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>

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

框架

客户端渲染框架将需要像 Webpack 这样的任务运行器或打包器来编辑、编码和压缩图片资源本身。例如,Responsive-loader 也使用 Sharp 库来重新保存图片资源。然后,它允许您将图片作为对象导入

  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 的 Image 组件等抽象来使用,或者直接填充您的响应式图片标记

<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 引入对 WebP 的支持和对输出 mime 类型的控制以来,API 不断得到改进。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> 元素进行艺术指导提供类似的钩子。