目前的前端图片加载优化技术有很多,像懒加载/预加载,img上的srcset属性以及picture标签,新的图片编码格式以及Client Hints等。

Client Hints

顾名思义,client hints是指通过客户端信息来进行资源选择的一种方法,由于用在图片加载上,所以这里的客户端信息一般是指图片宽度,DPR(device pixel ratio)和视窗宽度(viewport width)。其基本原理是在http传输中加入相关header,让服务器好选择一张合适的图片返回给客户端。

如何使用

要使用client hints,需要在添加一个meta标签,内容如下:

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width">

然后当浏览器向服务器请求图片的时候,就会附带上两个额外的header:

DPR: 2
Viewport-Width: 535

由此可知,客户端的像素密度是2,Viewport的宽度是535像素,这样服务器就能通过客户端信息来发送不同的图片了,这些图片既可以是已经存储的不同分辨率的图片,也可以即时地对图片大小进行转换,这取决于存储和计算之间的权衡。

兼容性

Cient Hints不是一个很新的东西,但它的兼容性却一般,可以作为一种渐进式用户体验的方法。 下面是它的浏览器兼容性:

image.png 可以看到,除了Chrome和Opera以及新版Edge之外全军覆没,所以这种方法见过的人少,用过的人更少了。下面就介绍一个一种更常用的方法。

Responsive images

如果说client hints是在服务器上对图片进行区分,那么Responsive images就是将这个过程放到浏览器上了。一般来说,组成Responsive images的标签和属性有img标签上的srcset,sizes属性,以及picture和source标签。

如何使用

关于srcset和sizes

理解这两者的最好方法就是用一个简单的例子,下面这个例子来自MDN:

<img srcset="elva-fairy-480w.jpg 480w,elva-fairy-800w.jpg 800w"sizes="(max-width: 600px) 480px,800px"src="elva-fairy-800w.jpg"alt="Elva dressed as a fairy">

首先,sizes决定了一个叫插槽的东西,顾名思义,就是留给这个图片的空间是多少,假设我放置这个图片的容器是800px,需要填满这个容器,那么就应该写成sizes=“800px”,同时,sizes支持使用媒体查询来区分不同的slot,不同的slot使用逗号分开,如上面的写法,意思就是当viewport宽度大于600px的时候,slot宽度为800px,否则为480px,当没有图片刚好匹配slot宽度时,浏览器会选择第一张比slot宽的图片。

其次,srcset决定了可以使用的图片来源,如上面的写法,就是说浏览器可以按照slot的宽度从宽度分别为480px和800px的两张图片中自动进行选择。

最后,src属性是当浏览器不支持srcset时候进行回退使用。

需要注意的是,srcset每张图片后面跟的宽度单位是w,代表图片文件的实际宽度,也即img.naturalWidth的宽度,为什么要用原生分辨率呢,其实道理很简单,我们可以想一下如果图片后面跟着的是css pixel的话,那么实际上浏览器是无法知道最合适的图片的,因为不同设备的DPR不一样,假设当前设备DPR为1,srcset=“elva-fairy-480w.jpg 480px”,表明想在slot宽度为480px的时候使用这张图片,但如果另一台设备DPR为2,很显然图片就会糊了,这样就达不到想要的效果了。所以最好的方式是告诉浏览器图片的原始分辨率,让它通过DPR和slot宽度自行判断需要使用哪个图片。

不需要使用sizes的情况

实际上,sizes并不是必须的,我们知道img作为替换元素,在没有css规定的情况下,它的大小由内容(也就是图片本身决定),也就是说浏览器在实际加载完成图片之前,都是无法知道img占的位置大小的,所以才需要sizes这个属性显式地规定slot的宽度,也就是程序员期望加载完图片之后占的宽度。

但如果使用css规定了img的大小:

img {width: 300px;height: auto;
}

这样的话,浏览器就能够知道img占的宽度,sizes也就变得不是必须了。

关于picture标签

picture标签实现的是根据媒体选择区分不同图片来源的功能:

<picture><source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg"><source media="(min-width: 800px)" srcset="elva-800w.jpg"><img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>

其中source标签标明可以选择的图片来源,浏览器会使用第一个匹配的source作为图片来源。如果像上面这样写,那么窗口宽度在大于等于800px的时候会使用第二个source,否则使用第一个source。

在最后一个source后面要加上一个img标签,一是为了在没有source匹配时有默认显示的图片,二是当浏览器不支持picture时可以平稳回退。

picture和srcset的区别

从上面的代码来看,picture和srcset实现了相似的功能,但实际上它们是很不一样的,从浏览器匹配的逻辑来看可以很明显地区分它们:

picture: media -> source
srcset: media -> slot -> source

可以看到srcset匹配的过程中多了一个slot,也就是说srcset匹配的图片依据的是图片所占空间,而picture匹配依据的是屏幕宽度。

同时picture可以根据图片格式进行选择:

<picture><source srcset="mdn-logo.svg" type="image/svg+xml"><img src="mdn-logo.png" alt="MDN">
</picture>

如果浏览器不支持svg,那么就会使用img中的png图像。

兼容性

从兼容性来看,Responsive images明显比Client Hints好的多,除了不争气的IE以外大部分新浏览器都支持。

图片格式

图片格式是优化图片加载的重要方式之一,除了常用的png/jpeg图像之外,现在常用的高压缩比+高质量的图片编码格式有WebP和AVIF等。

WebP

webp是Google搞得一种基于vp8视频帧编码的图片编码格式,前期兼容性一般,现在除了IE和safari之外的新浏览器大部分都支持:

AVIF

AVIF由开源组织AOMedia开发,Netflix、Google与Apple均是该组织的成员

有大公司撑腰,AVIF可以说前景比较光明,但其目前的原生兼容性不佳:

不过好在其有一个polyfill:Kagami/avif.js

这个polyfill使用service worker劫持fetch事件然后对avif图片进行处理,所以页面中的img标签可以直接引用avif文件:

<body><!-- Register worker --><script src="reg.js"></script><!-- Can embed AVIF with IMG tag now --><img src="image.avif"><!-- Or via CSS property --><div style="background: url(image2.avif)">some content</div>
</body>

当然,前提是需要浏览器支持service worker。

前端图片加载优化的各种技巧相关推荐

  1. 前端页面图片加载优化

    前端页面图片加载优化 问题:前端页面如果图片资源过多或者过大就会导致用户加载图片时间过长,导致用户体验下降 我总结的优化思路与方法有以下几种 一.将图标换成icon字体管理 如果项目存在大量的图表用的 ...

  2. 图片加载优化,拒绝OOM

    2019独角兽企业重金招聘Python工程师标准>>> 最近做了个资讯类的app项目,涉及到大量的图片加载,因公司项目框架已经集成了Glide用于加载图片,理所当然就直接用了Glid ...

  3. 网页图片加载优化方法总结

    目录 1.压缩 2.直接一开始用压缩过的体积小的图,等加载完毕后,再用高清无码图来替换掉 3.使用base64编码代替图片 4.更好的图片格式 5.合并图片sprite(雪碧图) 6.使用css.sv ...

  4. Android图片加载优化

    一.高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大 ...

  5. Swift - 表格图片加载优化(拖动表格时不加载,停止时只加载当前页图片)

    列表的单元格中包含有图片在开发中很常见.通常我们可以直接在tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIn ...

  6. iOS开发学无止境 - 异步图片加载优化与常用开源库分析

    作者:罗轩(@luoyibu) 网址:http://www.jianshu.com/p/3b2c95e1404f 1. 网络图片显示大体步骤:   下载图片 图片处理(裁剪,边框等) 写入磁盘 从磁盘 ...

  7. 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验

    这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验. 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器.我们用一些前端框架的 ...

  8. html加载时页面闪烁白色背景,解决页面加载闪白问题-背景图片加载优化

    页面加载闪白 今天遇到一个问题,写了一个使用深色背景图的网页,发现访问/刷新时,会出现短暂的闪白现象. 之前使用浅色背景时没有发现过这个问题,搜索半天也没有找到特别直白有效的回答. 找到的几个答案,有 ...

  9. Android图片加载优化方案

    1. 前言 在电商APP中,图片在整个页面中占比最大,清晰高质量的图片能够明显提升转化率.但是APP运行环境错综复杂,往往我们会遇到 图片压缩导致模糊.列表加载长时间显示空白图.查看大图黑屏过久.甚至 ...

最新文章

  1. javascript中实例方法与类方法的区别
  2. 思科PIX防火墙的实际应用配置
  3. 大学生计算机实验基础考试,大学生计算机基础考试试题
  4. 2021年春季学期-信号与系统-第十五次作业参考答案-第一小题参考答案
  5. Java实战应用50篇(二)-SSM框架中的设计模式:动态代理
  6. apache camel_Apache Camel中的断路器模式
  7. 查看mysql是否归档的命令_查看oracle数据库是否为归档模式
  8. Dubbo学习笔记002---安装Zookeeper_并且安装Dubbo的管理控制台
  9. IMP-00009: 导出文件异常结束 imp
  10. c语言中strncpy的用法,C语言中函数strcpy ,strncpy ,strlcpy的用法【转】
  11. 程序员,不甘平凡又害怕努力…
  12. bzoj 3437: 小P的牧场
  13. 从PCC到MIC,理解变量之间的相关性
  14. java画五角星_java 画五角星 填充五角星
  15. 江苏联亚国际展览中心跨境展批发产品B2B门户线上展会平台matchup expo SEO工作日志
  16. 五子棋-完美解决闪屏问题版-新增悔棋功能(C++实现)
  17. C学习笔记——(4)数组和字符串说明,以及冒泡排序法
  18. scheduler_tick函数详解
  19. Solr分词后,如何实现多个关键字完全匹配
  20. 国际码可以直接应用于计算机,2001年4月份全国高等教育自学考试计算机应用基础试题...

热门文章

  1. matlab 自动控制函数,matlab自动控制仿真常见函数应用.doc
  2. Virtual Box安装Linux
  3. HPC Game小结
  4. Vue动态修改网页浏览器标签的标题和图标
  5. 对于效率施工作业出力的另一途径采用路缘石滑模机
  6. 网络安全等级保护测评高风险判定
  7. 扑克牌面试问题:从牌顶拿出一张牌放到桌子上,再从牌顶拿一张牌放在手上牌的底部,重复第一步、第二步的操作
  8. python项目——外星人入侵游戏
  9. 【Get深一度】关于dB,那些你需要知道的常识
  10. 你们公司要求你写过如软著和专利吗?