了解 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"
/>
执行客户端渲染的框架是 Lazysizes 和 sizes="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>
元素进行艺术指导提供类似的钩子。