如何处理 Web 图片优化?

未优化的图片是影响网站性能的主要因素之一,尤为会影响初次加载。取决于图像的分辨率和画质,图片可能占据整个网站流量的 70%.前端

生产环境出现未优化的图片并显著影响初次加载速度的现象仍是挺常见的。缺少经验的开发者一般没有意识到这一潜在问题,也不了解各类优化图片的工具和方法。webpack

本文的目标是介绍优化 web 图片的主要工具和方法。git

计算 JPG 文件尺寸

未压缩图片的尺寸很容易计算,只需将图片的长宽相乘(px 值),再乘以 3 字节(由于 RGB 色彩系统使用 24 个位元)。所得结果除以 1,048,576(1024 * 1024)即获得兆字节。github

image_size = (image_width * image_height * 3) / 1048576

好比,计算分辨率为 1366px x 768px 的未压缩图片的大小:web

1366 * 768 * 3 / 1048576 = 3Mb

如今网站的尺寸平均在 2Mb 和 3Mb 之间,想象一下,一张未压缩的图片就占掉了 80% 的流量。在网速较慢的移动网络上,3Mb 大小的图片要花好久才能加载完毕。若是等待网站加载的用户大部分时间花在等待单张图片加载,那网站会损失很多流量。想一想就可怕,是吗?算法

因此,在保证图片分辨率和画质可接受的前提下,咱们能够作什么来优化下图片呢?npm

在线图片优化gulp

若是你的项目是一个简单的静态网站,只有少许不常常变更(甚至历来不会变更)的图片,那么你能够直接使用在线工具。这些工具使用各类算法压缩图像,效果很不错,对简单项目而言彻底够用。浏览器

就我我的所知,比较著名的在线工具备:服务器

  • Compressor.io,支持 JPG、PNG、SVG、GIF,每次上传 1 个文件
  • Squoosh,支持 JPG、PNG、SVG、GIF,每次上传 1 个文件
  • Optimizilla,支持 JPG、PNG,最多每次上传 20 个文件
  • TinyPNG,支持 JPG、PNG,最多每次上传 20 个文件
  • SVGMinify,支持 SVG,每次上传 1 个文件
  • svgomg,支持 SVG,每次上传 1 个文件

自动化解决方案

然而,若是你作的是多人协做的复杂项目,使用大量图片,在加入每张图片时都手动操做一下很乏味。同时,还存在因为人为错误或其余因素致使一些图片没有优化的风险。

复杂项目经常使用一样复杂的构建系统,好比 GulpWebpackParcel。配置一下这类构建系统,加入图片优化插件很方便。这样就能够彻底自动化图片优化过程,在项目中加入图片后就能够优化它们。

就我所知,最有名的插件是 imagemin,能够做为命令行工具使用,也能够做为构建工具的插件使用:

图片加载优化

咱们前面介绍了如何经过压缩图片下降文件尺寸,但不过多改变图片分辨率和影响画质。尽管优化图片后文件尺寸能下降很多,但一次性加载大量优化过的图片(好比电商网站的商品列表页面)仍是会影响性能。

懒加载

懒加载也叫按需加载,意思是仅加载当前视图(用户屏幕显示范围)内的图片,不加载其余图片(直到它们出如今当前视图内时才加载)。

只有较新版本的浏览器才支持原生的懒加载特性,不过有许多基于 JavaScript 的方案。

  • 原生懒加载
<img src="image.jpg" loading="lazy" alt="Sample image" />
  • 基于 JavaScript 的方案

就我所知,最知名的方案有:

verlok/lazyload
yall.js
Blazy (如今没有维护)

渐进式图片

尽管懒加载在性能方面表现出色,可是用户滚动屏幕后须要盯着空白区域等待图片加载,这样的用户体验不太好。网速慢的状况下,下载图片会很是慢。因此咱们还须要渐进式图片。

渐进式图片的意思是在高画质图像加载完以前会先显示低画质版本。低画质版本因为画质低、压缩率高,尺寸很小,加载很快。在二者之间咱们也能够根据须要显示不一样画质的版本。

相似于先加载页面的骨架,渐进式图片这一技术让用户产生图片加载变快的印象。用户再也不盯着一片空白区域等待事情发生,而能看到图像变得愈来愈清晰。
渐进式图片有基于 JavaScript 实现的方案:
progressive-image

响应式图片

咱们还须要留意使用尺寸合适的图片。

例如,假设图片在桌面浏览器上显示的最大宽度为 1920px,平板上的最大宽度为 1024px,手机上的最大宽度为 568px,那么最简单的方案是使用 1920px 的图片,这样能够知足全部场景。不过,这种状况下,网速慢、网络不稳定的智能手机用户须要等好久图片才能加载完毕,这就又碰到了咱们文章开头提到的问题。

好在咱们能够经过 picture 元素告诉浏览器基于媒体查询下载相应的图片。尽管如今 93% 的用户使用的浏览器都支持这一特性,可是这个元素内部仍是包含了一个 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

Cloudinary、Cloudflare 之类的 CDN 服务能够在服务器上优化图片,将优化后的图片传送给用户。若是你的站点使用 CDN,能够看下静态资源优化选项。这样咱们就不用操心图片优化,由 CDN 在服务端完成优化。咱们只须要操心懒加载、渐进式图片等前端的加载方案。

WebP 图像格式

WebP 是由 Google 开发的专为 web 优化的图像格式。根据 canIUse 的数据,大部分用户使用的浏览器支持 WebP 格式。另外使用 picture 元素也能够很方便地兼容不支持 WebP 的浏览器。

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

有不少在线文件格式转换工具能够把图片转为 WebP 格式,不过 CDN 服务能够在服务端完成这一格式转化。

为高分屏优化

考虑高分屏颇有必要,不过这个更多的是用户体验优化。

例如,假定咱们在 768px 的屏幕上显示一张 768px x 320px 的图片。可是屏幕有 2x 的密度,也就是说屏幕宽度实际是 2 x 768 = 1536 px。这就意味着咱们将 768 px 的图片拉升到 1536 px,这就致使高分屏上的图片看起来很模糊。

为了解决这一问题,咱们须要提供为高分屏优化的图片。咱们须要单首创建至关于普通屏幕 2 倍或 3 倍分辨率的图片,而后在 srcset 属性上使用 2x 标签代表这是为高分屏准备的图片。

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

结语 —— 优化优先级

  1. 使用优化后的图片(使用自动构建工具、在线服务、CDN 优化)
  2. 使用懒加载(在浏览器有更好的原生支持前考虑使用 JS 方案)
  3. 为高分屏优化图片
  4. 使用 WebP 格式
  5. 使用渐进式图片

可选: 若是条件容许,记得使用 CDN 加速图片(和其余静态资源)。

内容经受权转载自 New Frontend 网站。

相关文章
相关标签/搜索