作者:Simon_Diego | 来源:互联网 | 2023-08-24 14:11
本文由编程笔记#小编为大家整理,主要介绍了markdown ADMIN / WEB图片显示&size优化tradeoff分析相关的知识,希望对你有一定的参考价值。
# ADMIN/WEB 图片显示&size优化 tradeoff分析
## 影响图片size的因素
- Quality (q_85...)
- Dimension
- DPR (1.0, 2.0 - iPhone6/7/8, 3.0 - iPhone6/7/8 Plus/iPhoneX)
- Format (jpg, png, webp)
## 基本概念(术语)
### Format
- 除非特殊情况, 默认上传的图片都会转化为 .jpg 格式
- Admin图片链接部分参数说明
- [f_auto](https://cloudinary.com/documentation/image_transformations#automatic_format_selection),Cloudinary会自动将图片转换为浏览器能接收的最优格式,例如支持 webp的 Chrome
- [fl_lossy](https://cloudinary.com/documentation/image_transformations#applying_lossy_gif_compression),在对显示影响较小的情况下,Cloudinary会对图片进行有损压缩
- [c_fill](https://support.cloudinary.com/hc/en-us/articles/202521222-What-is-the-difference-between-Fill-Fit-and-Limit-scaling-modes-),对图片填充处理,
### Quality
- 图片 [quality默认为90](https://support.cloudinary.com/hc/en-us/articles/202521492-What-is-the-default-JPG-image-quality-for-derived-images-),也即是 q_90, cloudinary 显示的图片size是已经压缩过得size (目前只适用.webp)
### DPR
##### 物理像素(physical pixel)
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。
##### 设备独立像素(DPR: density-independent pixel)
设备独立像素(也叫密度无关像素),代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。
##### 设备像素比(device pixel ratio )
设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向
在Javascript中,可以通过 [window.devicePixelRatio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) 获取到当前设备的dpr。
在css中,可以通过 [-webkit-device-pixel-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-device-pixel-ratio) ,`-webkit-min-device-pixel-ratio` 和 `-webkit-max-device-pixel-ratio` 进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。
![DPR Illustration](https://res.cloudinary.com/cloudinary/image/upload/dpr_illustration.png)
以 iPhone6为例:
1. iPhone 6 display is 4.7 inches in size with a 16:9 resolution of 1334x750
2. 设备宽高为375×667,也即是设备独立像素(比如: css像素)。
3. 其 dpr为2,即1个css像素对应 4个物理像素(1:4),所以实际size为@2,750×1334。
## 分析
以 Klook 首页 Banner图片 ![](https://res.klook.com/image/upload/banner/y0ehj286wxl4lirq2rdb.jpg) (1920x600, 851.4 KB JPG) 为例
| 图片类型 | 参数 | 大小 | 相对比率 | 备注
| ------ | ------ | ------ | ------ | ------ |
| JPG | 不带参 | 853kb | 444% | 默认图片,尺寸为 1920 * 600,体积大
| WEBP | 不带参 | 192kb | 100% | webp 格式的体积只有 jpg格式的 22.5%
| WEBP | q_100 | 1.3mb | 693% | 相对于默认的 q_90而言,体积特别大 TBD
| WEBP | q_85 | 128kb | 67% | 目前 Klook的图片压缩质量大部分为 q_85
| WEBP | q_60 | 59.5kb | 31% | 发梢开始有点模糊了,图片显示质量下降相对明显了(非 retina屏)
| WEBP | dpr_1.0,w_1920,h_600 | 192kb | 31% | dpr参数需要带 w和 h才能生效,默认为1.0,体积和尺码等价于不带参数的 webp
| WEBP | dpr_2.0,w_1920,h_600 | 364kb | 189.6% | 尺码@2,3840 * 1200
| WEBP | dpr_3.0,w_1920,h_600 | 606kb | 315.6% | 尺码@3,5760 * 1800
1. 当图片像素点个数小于屏幕像素点(物理像素)个数时,图片会就近取色以填充像素,从而造成模糊
- 比如设定css像素为 20×20,20×20的图片在 retina屏下,会被填充为屏幕物理像素大小的图片,也即 40×40
![从小到大](http://www.uml.org.cn/mobiledev/images/201605052.jpg)
2. 当图片像素点个数大于屏幕像素点(物理像素)个数时,图片会通过算法(downsampling)去实现缩小,如此会造成图片缺少一些锐利度或者色差,但不会模糊
- 比如设定css像素为 20×20,40×40的图片在普通屏下,会被压缩为屏幕物理像素大小的图片,也即 20×20
![从大到小](http://www.uml.org.cn/mobiledev/images/201605053.jpg)
3. 只有当图片像素点个数与屏幕像素点(物理像素)个数 1:1 关系,图片才能获得最优的清晰展示
- 比如为了获得 DPR 2.0,css像素为 40×40 的清晰图片展示,需要原始size为80×80的图片,以免被有损放大/缩小
##### 因此,dpr主要作用于 Retina屏下,保证图片的显示效果,而提高高清屏显示效果,需要上传更大的原始size图片(比如@2图)
## 实现
- 自适应DPR
- JS - [脚本控制](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)
```Javascript
let cOnnection= navigator.connection || navigator.mozConnection || navigator.webkitConnection,
type = connection && connection.effectiveType || '4g', // 网络状态,需兼容不支持该接口的浏览器情况
drp = window.devicePixelRatio || 1,
drpVal = type === '4g' ? drp : 1,
imgUrl = `https://res.klook.com/image/upload/fl_lossy.progressive,q_85,dpr_${drpVal},f_auto/c_fill,,/v1526541190/banner/y0ehj286wxl4lirq2rdb.webp`
```
- CSS - [媒体查询](https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Media_queries)
```css
@media (-webkit-max-device-pixel-ratio: 3) {
i {
background-image: url('...@3.jpg')
}
}
```
- HTML - [响应式图片](https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)
```html
src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
```
- 脚本填补 - 先有模糊的图片, 然后再懒加载出比较大的原图,预先加载往后的图片
-
## 限制
`f_auto` & `dpr` 参数只有使用cloudinary CDN 才可以支持。目前无法使用
##### 建议,尽可能的对部分比较重要位置的图片至少进行@2倍的图片上传,并在展示上做高清处理
## Links
- #响应式图片
- #探究WebP一些事儿