图片内容分发网络

您可能已经熟悉内容分发网络 (CDN) 的核心概念:一个由分布式但互连的服务器组成的网络,可以快速有效地向用户交付资源。当文件上传到 CDN 提供商时,将在全球 CDN 网络的其他节点上创建副本。当用户请求文件时,数据将由地理位置上离该用户最近的节点发送,从而减少延迟。CDN 的分布式特性还在发生网络中断或硬件故障时提供冗余,并提供负载均衡以缓解流量高峰。

图片 CDN 可以提供所有这些好处,但有一个关键区别:能够根据用于访问图片 URL 的字符串转换和优化图片内容。

用户将规范的高分辨率图片上传到提供商,提供商将生成用于访问该图片的 URL

https://res.cloudinary.com/demo/image/upload/sample.jpg

尽管使用的确切语法会因提供商而异,但至少所有图片 CDN 都允许您更改源图片的尺寸、编码和压缩设置。Cloudinary 例如,通过以下语法对上传的图片执行动态调整大小h_ 后跟以像素为单位的数值高度,w_ 后跟宽度,以及一个 c_ 值,您可以使用该值指定有关应如何缩放或裁剪图片的详细信息

通过在文件名和扩展名之前向 URL 添加逗号分隔的值,可以应用任意数量的转换,这意味着可以通过请求图片的 img 元素的 src 按需操作上传的图片。

<img src="https://res.cloudinary.com/demo/image/upload/w_400/sample.jpg" alt="…">

当用户首次访问包含这些转换的 URL 时,将生成并发送按比例缩放到 400 像素宽度 (w_400) 的新版本图片。然后,新创建的文件将在 CDN 中缓存,以便可以将其发送给任何请求相同 URL 的用户,而不是按需重新创建。

尽管图片 CDN 提供商通常会提供 软件开发工具包 以方便高级用法以及与各种技术堆栈的集成,但仅此可预测的 URL 模式就使我们能够轻松地将单个上传文件转换为可行的 srcset 属性,而无需任何其他开发工具

<img
  src="https://res.cloudinary.com/demo/image/upload/w_1000/sample.jpg 1000w"
  srcset="https://res.cloudinary.com/demo/image/upload/w_1000/sample.jpg 1000w,
        https://res.cloudinary.com/demo/image/upload/w_800/sample.jpg 800w,
        https://res.cloudinary.com/demo/image/upload/w_600/sample.jpg 600w"
  alt="…">

我们能够使用现在应该很熟悉的语法手动指定所需的压缩级别:q_,是“质量 (quality)”的缩写,后跟压缩级别的数字简写

<img src="https://res.cloudinary.com/demo/image/upload/w_400,q_60/sample.jpg"  alt="…">

但是,您很少需要手动包含此信息,这要归功于大多数图片 CDN 提供的一组非常强大的功能:完全自动的压缩、编码和内容协商。

自动化压缩

图片 CDN 拥有的计算能力意味着它们能够提供一项非常强大的功能:分析图片的内容,以算法方式确定其理想的压缩级别和编码设置,就像您或我手动微调每张图片的压缩一样。

这些算法可以自动执行您可能在文件大小和感知质量之间进行权衡的决策,分析图片内容中可测量的质量下降迹象,并相应地微调压缩设置。与一刀切的手动压缩设置方法相比,这通常意味着文件大小的大幅减少。

尽管此过程听起来可能很复杂,但实现起来再简单不过了:对于 Cloudinary,在图片 URL 中添加 q_auto 即可启用此功能

<img src="https://res.cloudinary.com/demo/image/upload/w_1400/sample.jpg" alt="…">
<!-- 250 KB-->

<img src="https://res.cloudinary.com/demo/image/upload/w_1400,q_auto/sample.jpg" alt="…">
<!-- 134 KB-->

自动化编码和内容协商

收到图片请求后,图片 CDN 会通过浏览器随资源请求一起发送的 HTTP 标头(特别是 Accept 标头)确定浏览器支持的最现代编码。此标头指示浏览器能够理解的编码,使用与我们用于填充 <picture> 元素的 <source>type 属性的相同媒体类型

例如,将 f_auto 参数添加到资源 URL 中的图片转换列表,明确告诉 Cloudinary 提供浏览器能够理解的最有效编码

<img src="https://res.cloudinary.com/demo/image/upload/w_1200,q_auto,f_auto/sample.jpg" alt="…">

然后,服务器生成具有该编码的图片版本,并将结果缓存以供所有后续具有相同浏览器支持级别的用户使用。该响应包括一个 Content-Type 标头,以明确告知浏览器文件的编码,而与文件扩展名无关。即使使用现代浏览器的用户将请求以 .jpg 结尾的文件,该请求也会附带一个标头,告知服务器支持 AVIF,并且服务器将发送 AVIF 编码的文件,并明确指示将其视为 AVIF。

CDN user interface.

最终结果是一个过程,不仅使您无需创建备用编码文件和手动微调压缩设置(或维护执行这些任务的系统),而且无需使用 <picture>type 属性即可有效地将这些文件交付给用户。因此,仅使用 srcsetsizes 语法仍然可以为您的用户提供编码为(例如)AVIF 的图片,回退到 WebP(或仅针对 Safari 的 JPEG-2000),再次回退到最合理的旧版编码。

使用图片 CDN 的缺点更多是后勤方面的,而不是技术方面的,其中最主要的是成本。虽然图片 CDN 通常为个人使用提供功能强大的免费计划,但生成图片资源需要带宽和存储空间来上传、在服务器上处理以转换图片以及用于缓存转换结果的额外空间,因此高级使用和高流量应用程序可能需要付费计划。