[译]Web图片优化指南

861 阅读6分钟
原文链接:dev.to/prototyp/op…

未经优化或压缩的图片是网站初次加载性能不佳的主要原因之一,根据分辨率和质量,图片最终可能占网站总大小70%以上。本文旨在介绍优化Web图片的常用工具和方法。

计算JPG文件大小

图片的宽度px值 * 高度px值 * 3bytes (24bits,RGB颜色系统),可以得到图片的原始大小,再将结果除以1,048,576 (1024 * 1024),将值从byte转换为M。

image_size = (image_width * image_height * 3) / 1048576

例如,一个1366px * 768px的图片文件大小约为3M,当今网站的平均大小是2M~3M,3M在网速较慢的移动网络上需要花很长时间加载。如果用户要长时间等待网站加载并且大部分时间花在加载单个图片上,网站可能因此丢失流量。

所以,怎样能使用优化过的图片并且保持可接受的质量和分辨率?

在线图片优化

如果只是开发一个简单的静态网站,图片数量有限,并且不会经常改变,则可以将图片拖拽到众多的在线工具之一中,它们在压缩图片方面非常出色,对于简单的项目来说已经足够了。

知名网站有:

自动化解决方案

如果是更复杂的多人协作项目,并且使用大量图片,通常使用构建工具,如Gulp、Webpack、Parcel等,在构建配置中添加图片优化插件 (如imagemin),可以完全自动化图片优化过程。

图片加载优化

虽然优化图片可以大大减少图片文件的大小,但是一次加载多个图片也可能会对性能产生不良影响。

懒加载

懒加载指的是只加载必需的资源。这里指的是仅加载当前用户视窗内的图片,其他图片直到出现在用户视窗内才加载。

有许多基于JavaScript的懒加载方案,另外浏览器也引入了原生的懒加载方案。

基于JavaScript的懒加载

原生懒加载

<img src="image.jpg" loading="lazy" alt="Sample image" />

渐进式图片

虽然懒加载对性能有很大的改善,但是从用户体验的角度来看,用户在等待图片加载的时候看到的是空白,这就是渐进式图片的用武之地。

渐进式图片指的是在高质量图片加载完成之前,先向用户呈现低质量的图片。低质量图片由于质量低压缩率高,一般文件会小很多,所以加载起来很快。可以根据需要提供尽可能多不同质量的图片,也可以在每次下载时加载更高质量的图片。

这项技术给用户带来了速度上的错觉,用户看到的是正在加载的图片,并且随着加载的图片质量越来越高变得越来越清晰,而不是一直看着空白。

渐进式图片的JavaScript实现:progressive-image

响应式图片

还需要注意使用适当大小的图片。

例如,假设我们的图片在台式机上的最大宽度为1920px,在平板电脑上的最大宽度为1024px,在移动设备上的最大宽度为568px,最简单的方案是用1920px的图片覆盖所有情况,对吗?这样的话,网速慢的智能手机用户就需要等很长时间才能加载完这么大的图片。

幸运的是,可以使用picture元素告诉浏览器下载哪张图片,具体取决于媒体查询。picture元素有一个相当简单的回退功能,在其中嵌入img元素。

<picture>
  <source media="(min-width: 1025px)" srcset="image_desktop.jpg">
  <source media="(min-width: 769px)" srcset="image_tablet.jpg">
  <img src="image_mobile.jpg" alt="Sample image">
</picture> 

使用CDN

CDN服务 (如Cloudinary、Cloudflare ) 可以在服务器上进行图片优化,并将优化后的图片提供给用户。如果你的网站使用CDN,可以认真研究一下资源优化选项,这样就完全不用担心图片质量优化的问题,只需要研究通过懒加载或渐进式图片优化图片加载。

WebP图片格式

WebP是Google研发的专门针对网络优化的图片格式,根据canIUse的数据,当前浏览器对WebP图片的支持率约为80%,并且在picture元素内通过img提供一个标准的jpg图片作为回退也很简单。

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

有很多在线的文件转换器可以将图片转为WebP格式,CDN服务也可以在服务端轻松地执行格式转换。

高像素密度屏幕的优化

这是对用户体验的改善而不是性能,但是考虑到像素密度更高的设备也很重要。

例如,假设我们在 768px 的屏幕上显示 768px * 320px 的banner图,但是屏幕有2倍的像素密度,px宽度实际是 2*768=1536px,这样基本上是将 768px 的图片拉伸到 1536px,会导致图片模糊。

为了解决这个问题,需要针对高像素密度屏幕提供优化后的图片。具体操作是创建分辨率是常规屏幕2倍或3倍的图片,并使用带2x标签的srcset属性来获得更高分辨率的图片。

<img src="image-1x.jpg" srcset="image-2x.jpg 2x" alt="Sample image" />

🌰支持高像素密度屏幕的响应式WebP/PNG图片

<picture>
    <source srcset="./images/webp/hero-image-420-min.webp 1x, ./images/webp/hero-image-760-min.webp 2x" type="image/webp" media="(max-width: 440px)">
    <source srcset="./images/minified/hero-image-420-min.png 1x, ./images/minified/hero-image-760-min.png 2x" media="(max-width: 440px)">
    <source srcset="./images/webp/hero-image-550-min.webp 1x, ./images/webp/hero-image-960-min.webp 2x" type="image/webp" media="(max-width: 767px)">
    <source srcset="./images/minified/hero-image-550-min.png 1x, ./images/minified/hero-image-960-min.png 2x" media="(max-width: 767px)">
    <source srcset="./images/webp/hero-image-420-min.webp 1x, ./images/webp/hero-image-760-min.webp 2x" type="image/webp" media="(max-width: 1023px)">
    <source srcset="./images/minified/hero-image-420-min.png 1x, ./images/minified/hero-image-760-min.png 2x" media="(max-width: 1023px)">
    <source srcset="./images/webp/hero-image-760-min.webp 1x, ./images/webp/hero-image-960-min.webp 2x" type="image/webp" media="(max-width: 1919px)">
    <source srcset="./images/minified/hero-image-760-min.png 1x, ./images/minified/hero-image-960-min.png 2x" media="(max-width: 1919px)">
    <source srcset="./images/webp/hero-image-960-min.webp" type="image/webp">
    <source srcset="./images/minified/hero-image-960-min.png">
    <img  src="./images/minified/hero-image-960-min.png" alt="Example">
</picture>

结论

  • 使用优化后的图片(自动构建工具/在线服务/CDN)
  • 使用懒加载(JS解决方案直到原生方案支持更广泛)
  • 针对高像素密度屏幕优化图片
  • 使用WebP图片格式
  • 使用渐进式图片
    可选:如果可以,使用CDN提供图片和其他静态资源。