0


前端图片适配不同屏幕方案

预备知识:

设备独立像素,以下图的iphone12 Pro为例,390*844表示的就是设备独立像素(DIP),也可以理解为CSS像素
在这里插入图片描述

物理像素(设备像素),就是屏幕的分辨率,显示屏就是由一个个物理像素点组成的;
DPR(Device Pixel Ratio) 设备像素比,DPR = 物理像素 / 设备独立像素

在同样的css像素大小下,屏幕有不同的dpr,同样大小的图片渲染出来的效果会不一样;因此,为了在不同的 DPR 屏幕下,让图片看起来都不失真,我们需要为不同 DPR 的图片,提供不同大小的图片。有以下几个方案

方案一:媒体查询
通过相应的媒体查询,得知当前的设备的 DPR 值,使用对应的图片

#image{background:url([email protected])}@media(device-pixel-ratio: 2){#image{background:url([email protected])}}@media(device-pixel-ratio: 3){#image{background:url([email protected])}}

缺点:

  • 可能存在一些介于 1和2,2和3 之间的 DPR 值,匹配不到对应的
  • 注意: 需要注意语法需要的兼容性,需要添加前缀,譬如 -webkit-min-device-pixel-ratio,可以由 autoprefixer 插件解决

方案二:CSS 配合 image-set 语法
image-set 属于 CSS background 中的一种语法,image-set() 函数为设备提供最合适的图像分辨率,它提供一组图像选项,每个选项都有一个相关的 DPR 声明,浏览器将从中选择最适合设备的图像进行设置。

#imgage{/* 不支持 image-set 的浏览器*/background-image:url('[email protected]');/* 支持 image-set 的浏览器*/background-image:image-set(url('[email protected]') 2x,url('[email protected]') 3x
     );}

缺点:

  • 和方案一一样

方案三:srcset 配合像素密度描述符
img标签的srcset属性 可以根据不同的 dpr 拉取对应尺寸的图片

<divclass='image'><imgsrc='[email protected]'srcset='[email protected] 2x,
                [email protected] 3x'></div>

上面 srcset 里的 2x,3x 表示 像素密度描述符,当屏幕的 dpr = 2 时,使用 xxx@2x.png.png 这张图,以此类推
缺点:

  • 和方案一一样

方案四:srcset 属性配合 sizes 属性 w 宽度描述符
上述 3 种方案都存在统一的问题,只考虑了 DPR,但是忽略了响应性布局的复杂性与屏幕的多样性;
srcset 属性还有一个 w 宽度描述符,配合 sizes 属性一起使用,可以覆盖更多的面;
sizes定义图像元素在不同的视口宽度时,可能的大小值;

<imgsizes= “(min-width:600px)600px,300px"src="xxx.png"srcset= “[email protected],[email protected],[email protected],>

sizes = “(min-width: 600px) 600px, 300px” 的意思是:

  • 如果屏幕当前的 CSS 像素宽度大于或者等于 600px,则图片的 CSS 宽度为 600px
  • 反之,则图片的 CSS 宽度为 300px srcset = “photo@1x.png 300w, photo@2x.png 600w, photo@3x.png 1200w 里面的 300w,600w,900w 叫宽度描述符。

示例:
当前屏幕 dpr = 2 ,CSS 宽度为 375px。
当前屏幕 CSS 宽度为 375px,则图片 CSS 宽度为 300px(因为sizes定义了最小宽度,屏幕375px小于600px,所以图片的CSS宽度为300px)。分别用上述 3 个宽度描述符的数值除以 300。

  • 300 / 300 = 1
  • 600 / 300 = 2
  • 1200 / 300 = 4 上面计算得到的 1、 2、 4 即是算出的有效的像素密度,换算成和 x 描述符等价的值 。这里 600w 算出的 2 即满足 dpr = 2 的情况,匹配到xxx@2x.png这张图。

示例:
当前屏幕 dpr = 3 ,CSS 宽度为 414px。
当前屏幕 CSS 宽度为 414px,则图片 CSS 宽度仍为 300px

  • 300 / 300 = 1
  • 600 / 300 = 2
  • 1200 / 300 = 4 dpr = 3,2 不满足,因此匹配到 1200w 这张图。

JavaScript 方案实现图片的懒加载

通过 JavaScript 实现的懒加载,主要是两种方式:

  • 监听 onscroll 事件,通过 getBoundingClientRect API 获取元素图片距离视口顶部的距离,配合当前可视区域的位置实现图片的懒加载
  • 通过 HTML5 的 IntersectionObserver API,Intersection Observer(交叉观察器) 配合监听元素的 isIntersecting 属性,判断元素是否在可视区内,能够实现比监听 onscroll 性能更佳的图片懒加载方案 还有一种是类似于懒加载的方式,类似于虚拟列表
  • 使用 content-visibility: auto 实现图片内容的延迟渲染
<template><divclass="card"><divclass="img-container"><imgclass="img":src="props.url"/></div><divclass="title">{{ props.title }}</div><divclass="area">{{ props.area }}</div><divclass="collect">{{ props.collect }}人想要</div><divclass="price">
      ¥<spanclass="amount">{{ props.price }}</span></div></div></template><style>.card{content-visibility: auto;}</style>

不在可视区域内的内容,一开始是没有被渲染的,在每次滚动的过程中,才逐渐渲染,以此来提升性能;虽然当前页面可视区域外的内容未被渲染,但是图片资源的 HTTP/HTTPS 请求,依然会在页面一开始被触发;因此严格来讲它并不是一个懒加载的方式;

标签: 前端 图像处理

本文转载自: https://blog.csdn.net/weixin_43029824/article/details/135269814
版权归原作者 街角小强 所有, 如有侵权,请联系我们删除。

“前端图片适配不同屏幕方案”的评论:

还没有评论