图片优化

图片优化

图片在网页数据的传输中占据了非常大的流量,如何优化图片,对于前端页面加载的性能极其重要。本文讲述了比较常见的几种优化图片的技巧。

图片格式介绍

(1)JPEG

JPEG 是 Joint Photographic Experts Group 的缩写,不支持透明度,常用于网站的 Banner 图。JPEG 使用的是一种有损图像质量的压缩算法,压缩的越狠,图片的质量损失也就越大,图片的尺寸也就越小。根据你网站所能忍受的图片质量,来相应的选择压缩比:

(2)PNG

支持透明度,支持无损压缩,一般图片的尺寸都比较大

(3)GIF

适合放动画图片。

(4)WebP

🔥Google 2010 年提出的新的图像压缩格式算法,在 2013 年又推出 Animated WebP,即支持动画的 Webp。优点:更优的图像数据压缩算法、拥有肉眼识别无差异的图像质量、具备了无损和有损的压缩模式、Alpha 透明以及动画的特性。

PNG、JPG、WebP 压缩对比:

GIF 和 WebP 对比:

不同网络环境,加载不同尺寸图片

如下是京东网站首页占据 C 位的宣传图:

它的 URL 地址如下,你任意改变这张图片的 URL 里面的宽、高,放到浏览器里面重新进行请求,就可以得到相应大小的图片:

响应式图片

不同平台设备加载不同大小、甚至不同内容的图片!

CSS 媒体查询

@media all and (max-width: 600px) {
    img {
        width: 300px;
    }
}

@media all and (min-width: 600px) and (max-width: 1200px) {
    img {
        width: 900px;
    }
}

srcset、sizes、picture 和 source

(1)srcset 属性

img 标签的 srcset 属性定义了我们允许浏览器选择的图像集,以及每个图像的大小:

<img srcset="images/team-photo.jpg 1x, 
             images/team-photo-retina.jpg 2x, 
             images/team-photo-full.jpg 2048w,
             images/team-photo-default.jpg" 
     src="team-photo.jpg">

上述代码,srcset 属性给出了四个图像的 URL。1x2x 这个 x 代表 pixel density descriptor,代表当当前设备的像素密度是标准像素密度的 1 倍或 2 倍时,去加载对应的图片,这个值可以是浮点数2048ww 代表 width descriptor,也就是图片的以像素为单位的宽度,当浏览器的渲染器需要去渲染宽度为 2048 像素的图片的时候,就会使用这张图片,这个值必须是正整数

最后一个图像 URL images/team-photo-default.jpg 没有带 x 或者 w,这表示这张图片是一张候选图片,当 srcset 其它图片都没有匹配上的时候,那么就会使用这种图片。当然,候选图片是可选的,如果不提供,就会选择使用 src 图片作为默认图片。

(2)sizes 属性

srcset 提供了一个图片的候选集,但是选择哪个图片是浏览器决定的,我们无法灵活控制。如果想要自己根据屏幕的大小,来告诉渲染器去渲染多大尺寸的图片,可以引入 sizes 属性。

<img src="/files/16870/new-york-skyline-wide.jpg"
       srcset="/files/16870/new-york-skyline-wide.jpg 3724w,
               /files/16869/new-york-skyline-4by3.jpg 1961w,
               /files/16871/new-york-skyline-tall.jpg 1060w"
       sizes="((min-width: 50em) and (max-width: 60em)) 50em,
              ((min-width: 30em) and (max-width: 50em)) 30em,
              (max-width: 30em) 20em">

sizes 的格式:媒体查询条件 目标值

上述的 sizes 属性表示,当屏幕宽度位于 50em ~ 60em 的时候,渲染所需图片宽度为 50em,当屏幕宽度位于 30em ~ 50em 的时候,渲染所需图片宽度为 30em,当屏幕宽度小于 30em,渲染所需图片宽度为 20em。当渲染器所需渲染的图片宽度确定的时候,再去 srcset 中去匹配最接近该宽度的图片 URL 即可。

目标值的单位可以是:

  • 相对字体大小的单位:emex
  • 绝对单位:pxcm
  • Viewport(窗口) 百分比单位:vw

(3)picturesource

srcsetsizes 可以让网站根据屏幕大小来加载**内容相同的(虽然也可以不同,但不应该这样用)**不同大小的图片,如果还想根据不同的屏幕,显示不同内容的图片,例如电脑上显示如下比较宽的图:

而手机上为了突出人物,显示比较瘦的图:

可以使用 <picture><source> 标签来解决这个问题:

<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>

上述代码的 <img> 标签是必须提供,否则不会显示任何图片,当 <source> 的媒体查询条件都不满足的时候,<img> 将会显示 src 所指向的 URL 图片。

除此之外,<picture> 标签还可以根据浏览器所能渲染的图片格式来选择不同的图片:

<picture>
  <source type="image/svg+xml" srcset="pyramid.svg">
  <source type="image/webp" srcset="pyramid.webp"> 
  <img src="pyramid.png" alt="regular pyramid built from four equilateral triangles">
</picture>

当浏览器按照 <source> 出现的顺序,依次探测是否满足条件,如果满足,就加载相应图片。

懒加载

有很多库可以实现懒加载图片,例如 lazysizes。对于每一张图片,需要确定在其原图内容还未被浏览器渲染出来之前,这张图应该显示什么占位符,目前有两个库可以生成图像的占位符。当然,如果对于所有图片,都像是用一个统一的图片作为占位符,也未尝不可。

LQIP

LQIP 就是 Low Quality Image Placeholders (低质量图像占位符) 的缩写。

SQIP

上述 LQIP 是基于像素的解决方案,而 SQIP 是 SVG-based LQIP (基于 SVG 的低质量图像占位符) 的缩写,其实基于 SVG 的,在任何设备上都看起来很清晰。

下图展示的是一个效果图:

换一种方式来表达图片

Data URL

对于一些较小的图片,可以将内容直接内嵌在 URL 中,常见格式如下:

data:[<mediatype>][;base64],<data>

mediatype 标识图片的格式,例如 image/jpeg 等。

Image sprites (雪碧图)

对于 HTTP 1.X 协议,雪碧图(即多张小图片合成一张大图)的加载方式,是很多网站都会采用的技巧,这种方式的缺点是,如果某个应用图标需要更新,那么整张大图都需要替换。

然而对于 HTTP 2.0 协议的到来,加载多张小图是比较推荐的做法,因为多张图片本身的下载都会复用同一个连接。

参考

扫描下面二维码,在手机端阅读: