现代图片性能优化与体验优化指南-响应式图片解决方案
时间:2023-04-05 14:19:30
HTML5
本文是系列文章的第二篇。系列文章:现代图片性能优化与体验优化指南-图片类型与图片标签的使用图片资源在我们的业务中占有非常大的一部分,尤其是其带宽消耗非常巨大。图片的性能优化和体验优化在今天尤为重要。本文将从多个方面来阐述在当今各种新特性的世界中,我们如何尽可能地优化我们的图片资源的性能和体验。适配不同的屏幕尺寸以及DPR的下一个模块,我们来看看图片资源如何更好地适配不同的屏幕尺寸。首先会涉及到一个初步的知识,屏幕的DPR值。那么,什么是DPR?要理解DPR,你需要知道什么是设备无关像素和物理像素。DeviceIndependentPixels以iPhone6/7/8为例,这里我们打开Chrome开发者工具:Whatdoes375*667这里是什么意思,意思是deviceindependentpixels(DIP),也可以理解为CSS像素,也称为对于逻辑像素:device-independentpixels=CSSpixels=logicalpixels怎么记呢?CSS像素在这里用于记忆,即。我们设置了一个宽度为375px的div,刚好可以填满设备的一行,高度为667px,div的大小正好可以填满整个屏幕。物理像素都可以,那么什么是物理像素呢?我们去电商网站买手机的时候,总会看手机的参数。以京东上的iPhone7为例:可以看到iPhone7的分辨率是1334*750,这里描述的是屏幕的实际物理像素。物理像素,也称为设备像素。显示屏由物理像素组成,1334x750表示手机在垂直和水平方向上拥有的像素数。通过控制每个像素的颜色,屏幕可以显示不同的图像。屏幕上的物理像素从出厂之日起就是固定的,单位是pt。Devicepixel=physicalpixelDPR(DevicePixelRatio)设备像素比OK。有了以上两个概念,就可以顺理成章地推导出下一个概念了。DPR(DevicePixelRatio)设备像素比,这个和我们通常所说的视网膜屏(multiplescreen,Retinascreen)有关。设备像素比描述了在未缩放状态下物理像素和设备独立像素之间的初始比例关系。简单计算公式:DPR=物理像素/设备独立像素我们套用上面iPhone7的数据(取设备物理像素宽度和设备独立像素宽度计算):iPhone7的DPR=iPhone7的物理像素宽度/iPhone7的设备独立像素宽度=2750/375=2或者1334/667=2可以得到iPhone7的dpr为2,也就是我们常说的视网膜屏。视网膜显示屏是苹果公司“发明”的营销术语。Apple将dpr>1的屏幕称为Retina屏幕。在retina屏幕中,以dpr=2为例,4(2x2)个像素作为1个像素,让屏幕看起来更加精致,但是元素本身的大小并没有改变:OK,我们来看iPhone再次XSMax:它的物理像素如上图是2688x1242,它的CSS像素是896x414。很容易得出iPhoneXSMax的dpr是3。为不同的DPR屏幕提供合适的图片So,DPR和图像适配有什么关系?比如在相同的CSS像素尺寸下,如果屏幕有不同的DPR,那么同样尺寸的图片渲染出来的效果是不一样的。我们以dpr=3的手机为例。在300x389CSSpixelsize范围内,渲染1x/2x/3x图片效果如下:实际图片占用的物理像素为900x1167,可以看到,提供图片非常模糊在高DPR设备下只有CSS像素大小。因此,为了让图片在不同的DPR屏幕下看起来不失真,我们需要为不同DPR的图片提供不同尺寸的图片。那么,可能的解决方案是什么?方案一:无脑多图假设。在移动端,假设我们需要一张CSS像素为300x200的图片,考虑到我们已经有一个dpr=3的设备,我们必须保证图片在dpr=3的设备下才能正常高清显示,我们可能最多需要一张900x600的原始图像。这样不管设备的dpr是不是3,我们统一使用3倍的图像。这样即使在dpr=1和dpr=2的设备上,也能很好的显示画面。当然,这是不可取的,会造成大量的带宽浪费。现代浏览器提供了一种更好的方式,允许我们根据设备dpr提供不同尺寸的图像。方案二:媒体查询方案二,我们可以考虑使用媒体查询。今天我们通过对应的媒体查询就可以知道当前设备的DPR值,这样我们就可以在对应的媒体查询中使用对应的图片了。像这样:#id{background:url(xxx@2x.png)}@media(device-pixel-ratio:2){#id{background:url(xxx@2x.png)}}@media(device-pixel-ratio:3){#id{background:url(xxx@3x.png)}}这种方案的缺点是代码可能写的太多,1~2、2~DPR之间可能会有一些值在3之间,要穷举所有场景并不容易。需要注意语法要求的兼容性,需要加上前缀,比如-webkit-min-device-pixel-ratio。当然,这可以通过autoprefixer来辅助。方案三:CSS配合image-set语法image-set属于CSS后台的一个语法,image-set()函数提供了最适合设备的图像分辨率,它提供了一组图像选项,每个选项都有一个关联DPR声明,浏览器将从中选择最适合设备设置的图像。这是什么意思?我们看一下代码:.img{/*不支持image-set的浏览器*/background-image:url('../photo@2x.png');/*支持image-set的浏览器*/background-image:image-set(url('./photo@2x.png')2x,url('./photo@3x.png')3x);}在这个方式,功能应该很清楚。对于支持image-set语法的浏览器:如果设备对应的DPR为2,则会选择这条url('./photo@2x.png')2x记录,即最终有效的URL为'./photo@2x.png';如果设备对应的DPR为3,则选择此url('./photo@3x.png')3x记录,即最终有效URL为'./photo@3x.png';其中2x和3x用于匹配DRP。使用图像集的一些痛点类似于媒体查询解决方案。代码量和兼容性语法,很难匹配所有情况。方案四:srcsetwith1x2xpixeldensitydescriptor简而言之,srcset可以根据不同的dpr拉取相应大小的图片:1x,上面srcset中的2x
表示像素密度描述符,表示当屏幕的dpr为1时,使用images/illustration-small.png当屏幕的dpr为2时,使用images/illustration-big.png。如果这张图片不支持srcset语法,src='illustration-small.png'将是最终的解决方案。srcset属性配合1x以上的sizes属性w宽度描述符,2x更容易接受和理解。但是,以上三种方案存在一个统一的问题,只考虑了DPR,而忽略了响应式布局的复杂性和屏幕的多样性。因此,规范也引入了解决方案——srcset属性配合sizes属性w宽度描述符。srcset属性还有一个w宽度描述符,可以和sizes属性一起使用来覆盖更多的面。如何理解sizes属性?它为不同视口宽度的图像元素定义了可能的尺寸值。以下面的代码为例:
分析一下:sizes="(min-width:600px)600px,300px"意思是:如果当前屏幕的CSS像素宽度大于等于600px,那么图片的CSS宽度为600px;否则,图片CSS宽度为300px,即sizes属性声明了图片在不同宽度下的CSS宽度表现,这里可以理解为大屏下图片宽度为600px,图片宽度小屏下是300px,这里需要注意的是大屏,小屏下图片的具体宽度还是需要用到媒体查询代码,srcset="photo@1x.png300w,photo@2x.png600w,photo@3x.png1200w里面300w,600w,900w称为宽度描述符。那么,如何判断当前场景选择哪张图片呢?当前屏幕dpr=2,CSS宽度375px。当前屏幕的CSS宽度为375px,图片的CSS宽度为300px。将以上3个宽度描述符的值分别除以300。300/300=1600/300=21200/300=4上面计算的1、2、4是计算出的有效像素密度,可以换算成x和描述的字符等效值。这里600w计算出来的2满足dpr=2的情况,所以选择这张图。当前屏幕dpr=3,CSS宽度为414px。当前屏幕CSS宽度为414px,图片CSS宽度仍为300px。再计算一下:300/300=1600/300=21200/300=4。因为dpr=3,2已经不满足了,那么此时会选择1200w的图片。当前屏幕dpr=1,CSS宽度为1920px。当前屏幕的CSS宽度为1920px,图片的CSS宽度变为600px。再计算一下:300/600=.5600/600=11200/600=2由于dpr=1,此时会选择600w对应的图片。具体可以试试这个Demo:CodePenDemo--srcsetattributewithwwidthdescriptorandsizesattribute。该方案的意义在于兼顾了响应式布局的复杂性和屏幕的多样性。使用以上规则,一次性适配PC。终端大屏、移动端高清屏,一箭多鸟。好吧,总结一下,我们在实现响应式图像时同时使用了srcset和sizes属性。它们的作用是:srcset:定义多个不同宽度的图片源,让浏览器在HTML解析时选择最合适的图片源。sizes:定义不同视口宽度的图像元素时,可能的尺寸值有这些属性后,浏览器会根据srcset/size创建一个分辨率切换器的响应式图像,可以在不同的视口提供相同尺寸的图像分辨率,或提供不同视图大小的不同图像。图像的大小。本章小结本章一共列举了5种实现响应式图片、适配不同屏幕尺寸、不同DPR方式的方法。分别是:无脑多图方法DRP媒体查询CSS后台使用image-setsrcset和1x2x像素密度描述符srcset属性配合sizes属性wwidth描述合理使用,可以有效的为用户提供最合适的图片资源不同的屏幕,在保证用户体验的同时尽可能节省带宽。它们各有优缺点。大家可以根据自己的实际业务场景选择合适的、成本相对最低的方案,适当配合Autoprefixer和一些PostCSS工具来简化代码量。当然,本文只是现代画面性能优化与体验优化指南的第二部分。后续将为大家带来图片中的:图片宽高比、裁剪缩放显示延迟加载/异步图片解码方案易用性和图片资源容错和错误处理等相关知识的介绍,感兴趣的可以付费提前注意。最后OK,本文到此结束,希望本文对你有所帮助:)更多精彩的CSS技术文章汇总在我的Github——iCSS,持续更新中。欢迎点个星订阅收藏。有什么问题或者建议可以多交流。原创文章文笔有限,知识匮乏。如果文章中有任何不准确的地方,请告诉我。本文参加了SegmentFault思维写作挑战赛,欢迎正在阅读的你加入。