(九):图片断点
最后更新于:2022-04-01 03:43:06
> 原文出处:http://www.w3cplus.com/responsive/responsive-images-101-part-9-image-breakpoints.html
我其实很害怕写[响应式图片101系列](http://www.w3cplus.com/blog/tags/509.html)里图片断点这个部分。选择图片断点每个人都会遇到,坦白说,我也没有一个好的解决方案。
但我们迟早会遇到图片断点的问题。所以不妨现在就开始研究。
## 响应式图片断点是什么?
在响应式布局中,断点代表在某个视口尺寸上改变页面的布局或功能。通常与媒体查询相对应。
响应式图片断点与此类似但有细微差别。当我在思考图片断点时,我会尝试回答两个问题:
* 需要提供多少个图片源来包含此图片需要使用的场景?
* 在哪里以及什么时候应该使用这些图片?
这些问题的答案产生的断点会与响应式布局中标准的断点不同。在布局中,我遵循Stephen Hay的好方法:改变浏览器大小直到页面看起来很糟糕那么这个时候啊哈,我们需要一个断点。
然而在[艺术指导](http://www.w3cplus.com/responsive/responsive-images-101-definitions.html)中,需要多个图片源的原因和图片在什么浏览器尺寸下看起来很糟糕并无关系。我们想提供多个图片源是基于表现考虑,不同尺寸屏幕的分辨率等其他原因。
因此我们不能在图片上机械重复使用响应式布局断点。或者我猜也许是可以,但是如果这样做的话,那就和我们使用响应式图片的初衷背道而驰了。
## 艺术指导的图片断点相对简单
在[艺术指导使用情况中](http://www.w3cplus.com/responsive/responsive-images-101-definitions.html),艺术指导本身会告诉我们需要多少个图片源并且什么时候应该使用。
回顾Nokia浏览器网页的例子,我们可以知道图片应该在什么时候从风景模式转为肖像模式。发生转换时,需要一个新图片源。
然而,这也许只是图片的一部分。如果艺术指导的某一张图片包含了大范围的尺寸呢。我们会发现仍然需要与艺术指导切换不对应的多个图片源。
可以在[第8部分](http://www.w3cplus.com/responsive/responsive-images-101-part-8-css-images.html)提到的Shopify首页看到看到这个例子。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c745517b3c.gif)
虽然图片只有一个主要的艺术指导切换变化-从全尺寸的图片变成裁剪的版本-Shopify仍然提供了6个图片源说明图片尺寸和显示器分辨率。
~~~
<picture>
<source srcset="homepage-person@desktop.png, homepage-person@desktop-2x.png 2x"
media="(min-width: 990px)">
<source srcset="homepage-person@tablet.png, homepage-person@tablet-2x.png 2x"
media="(min-width: 750px)">
<img srcset="homepage-person@mobile.png, homepage-person@mobile-2x.png 2x"
alt="Shopify Merchant, Corrine Anestopoulos">
</picture>
~~~
了解图片在艺术指导使用情况下的表现让我们得到一些结论,但仍然没法回答关于必要图片断点的所有问题。
## 分辨率切换断点
这就是事情变得有技巧的地方。至少艺术指导给了我们一些关于需要多少图片源的提示。
当拉伸自适应图片时,它们总是表现良好。不能指望它们表现变差来告诉我们什么时候需要改变图片源。
来看一下分辨率切换的例子:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c745567246.jpg)
在这里例子中,当前页面视口尺寸中一张Michelle Obama的照片的尺寸为`400px x 602px`。这张图片的最大尺寸要在`2000px x 3010px`的分辨率下才会显示。最大文件的大小为`250K`。
可以直接缩放这张`2000px`的图片,并且它会表现良好。但是尺寸过大。如果提供一个小版本的图片例如分辨率`800px x 1024px`会显得更好。图片尺寸仅为`73K`。
我们都同意当页面中图片尺寸仅为`400px x 602px`时,提供一张分辨率为`800px x 1024px`大小为`73K`的图片会比下载最大尺寸的图片更好。
但为什么要止步于800×1204呢?
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c745581507.jpg)
如果我们提供另一张尺寸为`600px × 903px`的图片源,大小只有`42K`。这比`800px × 1024px`大小的图片节约了`31K`(`42%`)。
很棒。`42%`的空间节约是很大的进步。也许我们应该更进一步。如果是`500px`宽呢?`450px`宽呢?
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c7455a335c.jpg)
每个更小尺寸的图片都可能比之前的尺寸更节约空间。如果继续这种方式,最终会达到页面上这张图片的精确尺寸。
那么这里有一个令人困扰的关于图片断点的问题。如何确定当前页面使用的图片尺寸的文件大小太大了呢?
答案是除非图片源完全匹配图片显示在页面上的尺寸,否则它总是过大的。总是有机会提供更小尺寸的图片来优化。
## 为什么不提供精确的图片尺寸呢?
在这一点上,你也许会疑惑为什么不直接提供在页面中使用图片的精确尺寸呢。
首先,响应式设计中设定自适应图片断点的目的是让图片随着视口改变而伸缩。如果提供页面中使用图片的精确尺寸,不论是视口尺寸改变还是设备旋转都需要下载新图片。
其次,提供任何能想到尺寸的图片是不可能的。是的,我们可以动态改变图片尺寸,但与此同时,服务器需要处理这些工作就会拖慢分发图片到浏览器的速度。
因此,大多数网站把图片缓存在内容分发网络(CDN)上。要把每个尺寸的图片缓存在CDN上是非常昂贵的。
最后,[浏览器在开始下载时并不知道页面中图片的确切尺寸](http://www.w3cplus.com/responsive/responsive-images-101-part-4-srcset-width-descriptors.html)。这就是最初让我们制定响应式图片新标准的原因。
## 选择图片断点的可行方法
像开始提到的那样,我没有绝对可靠的关于如何选择需要图片源数量的方案。相反,我想阐述一些看待这个问题的不同方式来帮助你做决定。
## 让它飞起来(又叫做,匹配布局的断点)
你团队中的某些人会说,“嗨,你觉得这些产品图片需要多少图片源?”
你犹豫了一会儿说,“3个怎么样?小,中,大。”
如果你已经这么做了也不要羞涩。我很确定现在大部分使用响应式图片的人已经这么做了。
也许你的考量中需要兼容手机,平板和桌面也就是小,中,大屏幕。
或者你考虑到图片会显示的范围并估计一下。也许你只是简单看一下主流的断点数量然后决定同样处理图片断点。
我完全理解。显然这比给所有视口提供一张大图片要好。
当然如果我们的决定更有逻辑会更好。
## 测试响应式图片
可能猜测听起来也不是很奇怪,让我们在选择图片断点中加入一些科学成分。我们来看一些响应式图片并计算出它们需要多少断点。
这件事情最难的部分是限制响应式图片,或计算出总共有多少个图片。
对于一些网站,所有照片可能按照品牌有特定样式。如果是这种情况,很容易找到具体的有代表性的图片。选择一些图片改变尺寸并保存最大和最小图片间的尺寸直到你认为已经得到了合适的范围。
当然,如果你的网站有多种多样的图片样式,找到具有代表性的图片几乎是不可能的。
## 内存消耗对图片断点分布的影响
今年夏天早些时候,[Tim Kadlec](http://timkadlec/)发表了一个关于[手机图片过程](https://www.youtube.com/watch?v=jP68rCjSSjM)的演讲。在这个演讲中,他主要研究了响应式设计中自适应图片的内存开销。
Tim展示了随着图片增大,改变图片尺寸的影响也变大了。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c7455dba12.png)
在上述例子中,在每个方向上将一张`600px × 600px`的图片减少`50px`会导致`230000b`的浪费相比于用同样方式将`200px × 200px`减少`50px`只有`70000b`的浪费。
这一点给我们提供了一些选择断点的参考。并不是要使断点均匀分布,在图片变大时应该增加更多断点。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c7455eb0a2.png)
不幸的是,虽然这一点告诉我们大尺寸图片需要更多断点,我们依然不知道具体在哪里需要这些断点。
## 基于绩效预算设置图片断点
如果我们把绩效预算的灵感应用到响应式图片?这样会看起来如何呢?
我们给浪费的比特数定义一定数量的预算,浏览器下载适应当前页面的图片时可以在这范围内造成一定的比特浪费。
因此我们决定每个响应式图片的绩效预算为`20K`。这意味着必须确保定义的各种图片源都小于`20K`。
这样做后,我们发现图片断点基于视觉多样性发生了巨大的改变并且使用了压缩。
让我们来看三张样例图片。
### 时代广场-8个图片断点
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c7456031bc.jpg)
这张图片的视觉多样性丰富。颜色和纹理变化意味着无法在保证图片质量的情况下进行很大程度的JPEG无损压缩。
因此,这张图有8个图片断点-以20k为间隔设置-最小图片尺寸为(`320×213`),最大图片尺寸为(`990×660`)。
| Breakpoint # | Width | Height | File Size |
| --- | --- | --- | --- |
| [1](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-320x213.jpg) | 320 | 213 | 25K |
| [2](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-453x302.jpg) | 453 | 302 | 44K |
| [3](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-579x386.jpg) | 579 | 386 | 65K |
| [4](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-687x458.jpg) | 687 | 458 | 85K |
| [5](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-786x524.jpg) | 786 | 524 | 104K |
| [6](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-885x590.jpg) | 885 | 590 | 124K |
| [7](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square-975x650.jpg) | 975 | 650 | 142K |
| [8](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/times-square.jpg) | 990 | 660 | 151K |
### 凯特林的早晨-3个图片断点
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c745620e3f.jpg)
不像时代广场的图片,这张图片很多地方颜色非常相似并且纹理很少。因此,JPEG能更好得压缩这张图片。
在一张能被良好压缩的图片上,20K的预算可以更进一步。对于这张图片,我们只需要三个图片断点来覆盖这张图片会使用的所有尺寸区间。
| Breakpoint # | Width | Height | File Size |
| --- | --- | --- | --- |
| [1](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/kettering-sky-320x213.jpg) | 320 | 213 | 9.0K |
| [2](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/kettering-sky-731x487.jpg) | 731 | 487 | 29K |
| [3](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/kettering-sky.jpg) | 990 | 660 | 40K |
### 微软logo-1个图片断点**
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-10-13_561c745634c43.png)
这是一张简单的PNG8文件。最大尺寸(`990×660`)的大小仅为`13K`。因此,它不用做任何改变就适合我们的`20K`预算。
| Breakpoint # | Width | Height | File Size |
| --- | --- | --- | --- |
| [1](http://www.w3cplus.com/sites/default/files/blogs/2015/1510/Microsoft_Logo.png) | 990 | 660 | 13K |
来看一下我们创建的[样例页面](http://cloudfour.com/examples/image-breakpoints/)上的其他图片。了解断点数量如何变化即便所有图片开始时分辨率相同且最终断点相同。
现在,我并没有建议大家手动决定每个图片的断点。但是未来你可以在服务器上声明20K的响应式图片预算然后让服务器计算每张图片的图片源数量。
我过去已经写过了更多关于[响应式图片的绩效预算](http://blog.cloudfour.com/sensible-jumps-in-responsive-image-file-sizes/)内容的细节。如果你最终施行了这个方法,请告诉我。
## 基于请求的频繁程度设置图片断点
最近的[响应式图片讨论组(RICG)](http://responsiveimages.org/)中,[Yoav Weiss](http://blog.yoav.ws/) 和 [Ilya Grigori](https://www.igvita.com/)讨论了一个基于图片尺寸请求的频繁程度来选择图片断点的方式。
对于在Akamai工作的Yoav和在Google工作的lily来说,他们对于多图片的一个共同问题在于把这些源都存在[边缘服务器](http://www.nczonline.net/blog/2011/11/29/how-content-delivery-networks-cdns-work/)上然而存储空间通常有限制并且代价更加昂贵。
不光是像Akamai和Google这样的公司想要减少边缘服务器上存储的图片数量,它们内容分发网络的整个目的都是减少人们耗费在web页面渲染上的时间。
因此,如果能够把请求最频繁的图片尺寸缓存在边缘服务器,它们会给大多数用户带来最快的分发体验。
对于这些组织,他们可以把图片处理和断点逻辑与分析系统联系起来并且一旦发现新的图片尺寸被更频繁得请求后便改变图片的尺寸。
当把它与Ilya已经实现新[HTTP客户端提示](https://tools.ietf.org/html/draft-grigorik-http-client-hints-03)特性结合起来时,服务器对于如何在CDN上保存图片会变的非常聪明,这样做的话很少需要设计师和开发来做决策。
## 人们不应该手动去做
我相信在短短几年内,没有人会再谈论选择响应式图片断点因为没有人会再手动去做。
当然,我们仍然会对艺术指导使用情况的图片作出决定,但即便是这个情况,我们当然不会给每个图片源做决定。我们只处理需要介入的部分然后让图片处理服务解决剩余部分。
根据绩效预算或不同尺寸的请求频繁程度来选择图片源都有一大堆好处。但这些解决方案作为手动工作流的一部分都站不住脚。
未来,我们的工作流也许是将最高品质的图片上传到内容管理系统或图片处理系统并且再也不要关心。
[这个系列](http://www.w3cplus.com/blog/tags/509.html)一开始有9个部分,但是讨论响应式图片时总有许多要说。最后补允一篇,用来总结响应式图片的使用。