使用下一代高性能图像技术

608 阅读6分钟

写在前面

还记得以前当切图仔年代,Photoshop想高保真输出的图像也是比较大。不得不把切好的图再批量上传到TinyPNG压缩,压缩后都是无损或者说看不出有损的图像。大大提升网站访问速度,再到前端工程化,将这项工作就交给Webpack等构件工具。

对于图片格式的使用相信大多数前端同学都是使用jpg、png、gif等图像格式。这可谓图像格式三分天下的局面。随着图像技术更迭,下一代图像格式将打破这个种局面。 对于同一图像的多种分辨率我们通常会通过媒体查询来处理,现在也许只要利用 image-set、img标签的srcset 属性、又或者我们比较陌生的picture标签就可以很容易设置。还有CSS新增的object-fitclip-path属性,包括上一篇文章 每个前端都需要知道这些面向未来的CSS技术提及到的混合模式和滤镜都是类似Photoshop对图像作处理。接下来让我们看看这些下一代的图像技术新特性。

下一代图像格式WebP

WebP,是一种同时提供了有损压缩与无损压缩的图片文件格式,派生自视频编码格式 VP8。WebP 最初在2010年发布,目标是减少文件大小,但达到 和 JEPG 格式相同的图片质量,希望能够减少图片档在网络上的发送时间。2011年11月8日,Google 开始让 WebP 支持无损压缩和透明色的功能。

根据 Google 较早的测试,WebP 的无损压缩比网络上找到的PNG档少了45%的文件大小,即使这些 PNG 档在使用 PNGCRUSH 和 PNGOUT 处理过,WebP 还是可以减少28%的文件大小。就目前而言,Webp 可以让图片大小平均减少70%。WebP 是未来图片格式的发展趋势。

WebP 的应用场景及优势:

  • 客户端软件,内嵌了基于 Chromium 的 webview,这类浏览器中应用的网页是可以完全使用WebP 格式,提升加载渲染速度,不考虑兼容。
  • 用 node-webkit 开发的程序,用 WebP 可以减少文件包的体积。
  • 移动应用 或 网页游戏 ,界面需要大量图片,可以嵌入 WebP 的解码包,能够节省用户流量,提升访问速度优势:
  • 对于 PNG 图片,WebP 比 PNG 小了45%

目前国内外各大互联网公司已逐步使用WebP,科技博客GigaOM曾报道,YouTube的视频缩略图采用WebP后,网页加载速度提升了10%;谷歌网上应用商店采用WebP后,每天可节省几TB的带宽,页面平均加载时间大约减少1/3;谷歌移动应用市场采用WebP图片格式后,每天节省了50TB的存储空间;2014年腾讯新闻客户端应用了WebP后,流量峰值带宽降低9GB,网络连接延时不变的前提下,平均图片延时和数据下载延时降低了100ms。

除了WebP,还有AVIF、HEIF和JPEG XL等等下一代图像格式,有兴趣可以去了解一下。

CSS的image-set

image-set()自 2012 年以来,基于 Chromium 的浏览器和 Safari 自第 6 版开始支持CSS功能。最近支持Firefox 88

.img { 
background-image: image-set(
"platypus.png" 1x,
"platypus-2x.png" 2x);
}

1x用于识别低分辨率图像,而2x用于定义高分辨率图像。x是 的别名dppx,代表每像素单位的点数

目前需要-webkit-前缀。如果您使用 Autoprefixer,这将自动处理。Safari 不再需要前缀,而是使用需要url()函数来指定图像路径的旧语法。我们还可以包含一个常规的 background-image: url()来兼容任何不支持image-set

.img { 
/* Fallback */ 
background-image: url("platypus.png"); 
/* Chrome/Edge/Opera/Samsung, Safari will fallback to this as well */ 
background-image: -webkit-image-set(url("platypus.png") 1x, url("platypus-2x.png") 2x); 
/* Standard use */ 
background-image: image-set("platypus.png" 1x, "platypus-2x.png" 2x); }

CSS的object-fit

object-fit属性有点类似于background-size的功能,可以很好的帮助我们来处理img、video的适配效果。其还有另一个属性是object-position,该属性有点类似于background-position。

object-fit一共有五个值,每个值所起的效果都不一样,比如下图所示的效果:

image.png

CSS的clip-path

clip-path提供了一些函数功能,比如polygon()circle()ellipse()inset()可以帮助我们绘制一些基本的形状,如下图所示:

image.png

使用clip-path可以实现一些不规则图形的效果,比如你想你的用户头像的效果个性化一点,那么就可以使用polygon()函数:

.avatar { 
    clip-path: polygon(0% 5%, 100% 0%, 100% 85%, 65% 80%, 75% 100%, 40% 80%, 0% 75%); 
}

img标签的srcset属性

img 元素的 srcset 属性用于浏览器根据宽、高和像素密度来加载相应的图片资源。

属性格式:图片地址 宽度描述w 像素密度描述x,多个资源之间用逗号分隔。例如:

<img src="small.jpg " srcset="big.jpg 1440w, middle.jpg 800w, small.jpg 1x" />

上面的例子表示浏览器宽度达到 800px 则加载 middle.jpg ,达到 1400px 则加载 big.jpg。注意:像素密度描述只对固定宽度图片有效。

img 元素的 size 属性给浏览器提供一个预估的图片显示宽度。

属性格式:媒体查询 宽度描述(支持px),多条规则用逗号分隔。

<img src="images/gun.png" 
         srcset="images/bg_star.jpg 1200w, images/share.jpg 800w, images/gun.png 320w"
         sizes="(max-width: 320px) 300w, 1200w"/>

上面的例子表示浏览器视口为 320px 时图片宽度为 300px,其他情况为 1200px。

picture标签

这个标签日常开发相信很多同学都比较少接触,其实HTML多年来一直支持该标签。

<picture>
<source srcset="./img.webp" type="image/webp">
<img src="./img.jpg" alt="a small kitten">
</picture>

image-set 也提供等效的 CSS,允许通过指定图像的 MIME 类型来使用下一代图像格式:

.img {
background-image: image-set( "kitten.webp" type("image/webp"),
            "kitten.jpg" type("image/jpeg") );
}

image.png

有时候这种效果我们第一时间就想去用background-image + position 来做 也许你根本不需要。

<div>
<picture>
  <source srcset="https://assets.codepen.io/429997/abstract_space.jpeg?width=896&height=539&format=avif" type="image/avif"
>
  <img 
src="https://assets.codepen.io/429997/abstract_space.jpeg?width=896&height=539&format=auto
" alt="">
</picture>
  <h1>Example text over image</h1>
</div>
body {
  margin: 0;
  color: white;
  font-family: system-ui, sans-serif;
}       

div {
    position: relative;
    width: 100%;
    height: 291px;
}
        
 img {
       position: absolute;
       object-fit: cover;
       height: 100%;
       width: 100%;
}

  h1 {
       position: relative;
       text-align: center;
       margin: 0;
}

写在最后

到这里先分享这些,更多笔者以后再分享,比如针对 AVIF、HEIF和JPEG XL等等下一代图像格式来探索一下。留意我的专栏你不知道的css这里我收集更多css相关新技术,新特性。