网页性能优化图片

38次阅读

共计 8588 个字符,预计需要花费 22 分钟才能阅读完成。

网页性能的优化:

  • 资源合并与压缩(html/css/js 压缩合并)
  • 图片相关优化(不同业务场景选择不同的图片格式,雪碧图等)
  • css/js 装载与执行(引用先后顺序及方式,是否阻塞,相互之间的依赖关系)
  • 懒加载/预加载(dns 预读取、多个 CND 域名、异步读取 JS(script 的 defer、async))
  • 缓存优化
  • 重绘与回流

网页性能测试工具

工具:Lighthouse 是一个 Google 开源的自动化工具,主要用于改进网络应用(移动端)的质量。目前测试项包括页面性能、PWA、可访问性(无障碍)、最佳实践、SEO。Lighthouse 会对各个测试项的结果打分,并给出优化建议,这些打分标准和优化建议可以视为 Google 的网页最佳实践。
工具安装:

  1. Chrome 开发者工具(Devtools)的 Audits,作为 Chrome 拓展程序使用,或者作为命令行工具使用(仅能在 Chrome60 及以上使用)

2. 命令行工具:

npm install -g lighthouse
lighthouse https://example.com
// 配置项查看 lighthouse --help

常见的图片及特点

矢量图与位图

我们的电脑在显示图片的时候也可以分为这两种:矢量图与位图

  1. 矢量图:

(矢量:既有大小又有方向的量,也称为向量)
也称为面向对象的图像或绘图图像,矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。
优点:
(1)文件小,图像中保存的是线条和图块的信息,所以矢量图形文件与分辨率和图像大小无关,只与图像的复杂程度有关,图像文件所占的存储空间较小
(2)图像可以无限缩放,对图形进行缩放,旋转或变形操作时,都不会不会产生锯齿效果或者模糊
(3)可采取高分辨率印刷,矢量图形文件可以在任何输出设备打印机上以打印或印刷的最高分辨率进行打印输出
缺点:
(1)难以表现色彩层次丰富的逼真图像效果
(2)暂时还不存在一种标准格式和标准处理流程,目前主要有 SVG 和 Adobe Flash。因此处理矢量图只能靠 CPU
适用场景:图形设计、文字设计和一些标志设计、版式设计等。

  1. 位图:

位图又叫像素图或栅格图,它是通过记录图像中每一个点的颜色、深度、透明度等信息来存储和显示图像。一张位图就好比一幅大的拼图,只不过每个拼块都是一个纯色的像素点,当我们把这些不同颜色的像素点按照一定规律排列在一起的时候,就形成了我们所看到的图像。所以当我们放大一幅像素图到一定程度时,能看到拼片一样的像素点
优点:
(1)利于显示色彩层次丰富的写实图像
缺点:
(1)一定程度的缩小或者放大都会让位图变形失真
(2)文件较大
我们在 web 页面中所使用的 JPG、PNG、GIF 格式的图像都是位图,即使他们都是通过记录像素点的数据来保存和显示图像,但这些不同格式的图像在记录这些数据时的方式却不一样,这就是涉及到有损压缩和无损压缩的区别——是否失真。

无压缩、有损压缩、无损压缩

  1. 无压缩。无压缩的图片格式不对图片数据进行压缩处理,能准确地呈现原图片。BMP 格式就是其中之一。
  2. 无损压缩。压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的尺寸。png 是其中的代表。
  3. 有损压缩。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的尺寸。其中的代表是 jpg。

聊一聊常见的 web 图片格式

  1. gif

GIF 是 CompuServe 公司在 1987 年开发的,是一种无损 (100% 的保持原始图片的像素数据信息) 的 8 位 (存储 8 位索引, 也就是最多能表达 2^8=256 种颜色) 图片格式,色彩复杂、细节丰富的图片不适合保存为 gif 格式。
特点:
(1)透明特性:GIF 支持基本的透明特性,这意味着你能够使图片的某些像素“不可见”。在其被放置到网页中时,我们就可以看到通过这些不可见区域看到此图片后面的背景颜色(图片)。
(2)压缩特性:GIF 格式采用 LZW 算法进行压缩,此算法是 Unisys 申请的一项专利。在十多年前,如果你想使用 GIF 格式,你还要给 Unisys 公司交专利费的。不过这项专利技术已于 2003 年 6 月 20 日过期,我们现在使用 GIF 是完全免费的。
(3)快速加载特性:GIF 同时也支持隔行扫描。隔行扫描能够令图片在浏览器中更快的加载和显示。这种特性能够提升慢网速用户的用户体验。
(4)动画 GIF:一个动态的 GIF 文件,是由若干帧图片所联结而成的动态图片。在显示时,这些动态帧被反复的绘制读取出来从而形成了简单的动画效果。

  1. jpg

是一种有损的基于直接色的图片格式,JPG(JPEG),文件后缀名为 ”.jpg” 或 ”.jpeg”,由于采用直接色,jpg 可使用的颜色有 1600w 之多(2^24),而人眼识别的颜色数量大约只有 1w 多种,因此 jpg 非常适合色彩丰富图片、渐变色。jpg 有损压缩移除肉眼无法识别的图片细节后,可以将图片的尺寸大幅度地减小。
特点:
(1)表现力强,能较好地摄影作品或写实作品;
(2)可以利用可变的压缩比来控制文件大小;
(3)JPG(JPEG)兼容性较好;
(4)有损耗压缩会使原始图片数据质量下降,当我们编辑和重新保存 JPG(JPEG)文件时,JPG(JPEG)会混合原始图片数据的质量下降。这种下降是累积性的;
(5)JPG(JPEG)不适用于所含颜色很少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片(例如 icon、logo,相比 gif/png-8,它在文件大小上毫无优势)。

  1. png

png 的产生一定程度上源于 gif,初始是被当作 gif 的免费替代格式而生,采用公共专利压缩算法。
PNG-8
是基于 8 位索引色的位图格式,最多只能索引 256 种颜色,所以对于颜色较多的图像不能真实还原;
特点:
(1)相比 gif 对透明的支持更好,同等质量下,尺寸也更小
(2)不支持动画
PNG-24
是基于直接色的位图格式,可以保存 1600 多万种颜色,这基本能够真实还原人类肉眼所可以分别的所有颜色。
特点:
(1)png-24 的图片质量堪比 bmp,但是却有 bmp 不具备的尺寸优势
(2)因为其高品质,无损压缩,非常适合用于源文件或需要二次编辑的图片格式的保存
(3)图片存储为 png-24 比存储为 jpg,文件大小至少是 jpg 的 5 倍,但在图片品质上的提升却微乎其微,所以除非对品质的要求极高,否则色彩丰富的网络图片还是推荐使用 jpg

  1. webp

WebP 图片是一种采用有损和无损压缩的图像格式,由 Google 开发,是基于 VP8 视频格式的衍生产品, 目标是减少文件大小但达到和 JPEG 格式相同的图片质量,能够减少网络上的请求时间。
历史:
(1)该格式于 2010 年 9 月 30 日首次公布,作为网络上有损压缩真彩色图形的新开放标准,生成与旧 JPEG 方案相当的较小文件质量
(2)2011 年 10 月 3 日,Google 宣布 WebP 支持动画,ICC 配置文件,XMP 元数据和平铺(合成来自最大 16384×16384 平铺的非常大的图像)
(3)2011 年 11 月 18 日,谷歌开始尝试无损压缩和无损和有损模式下的透明度(alpha 通道)支持,而在 2012 年 8 月 16 日的参考实做 libwebp 0.2.0 中正式支持
优点:
(1)与 png、jpg 相比,相同的视觉体验下,WebP 图像的尺寸缩小了大约 30%。(意味着更小的体积,更高的质量)
(2)WebP 图像格式还支持有损压缩、无损压缩、透明和动画。理论上完全可以替代 png、jpg、gif 等图片格式
缺点:
(1)目前 webp 的还没有得到全面的支持,参考 webp 兼容性。
(2)根据 Google 的测试,目前 WebP 与 JPG 相比较,编码速度慢 10 倍,解码速度慢 1.5 倍(编码方面,一般来说,我们可以在图片上传时生成一份 WebP 图片或者在第一次访问 JPG 图片时生成 WebP 图片,对用户体验的影响基本忽略不计。
解码方面,WebP 虽然会增加额外的解码时间,但由于减少了文件体积,缩短了加载的时间,页面的渲染速度加快了。同时,随着图片数量的增多,WebP 页面加载的速度相对 JPG 页面增快了)

图片选择总结:

格式 优点 缺点 适用场景
gif 文件小,支持动画、透明,无兼容性问题 只支持 256 种颜色 色彩简单的 logo、icon、动图
jpg 色彩丰富,文件小 有损压缩,反复保存图片质量下降明显 色彩丰富的图片 / 渐变图像
png 无损压缩,支持透明,简单图片尺寸小 不支持动画,色彩丰富的图片尺寸大 logo/icon/ 透明图
webp 文件小,支持有损和无损压缩,支持动画、透明 浏览器兼容性不好 支持 webp 格式的 app 和 webview

附加

  • FLIF 是一种正在进行中的无损图像格式,声称在压缩率方面优于 PNG,无损 WebP,无损 BPG 和无损 JPEG2000,于 2015 年推出
  • BPG,一种图像格式,旨在成为 JPEG 图像格式的更高压缩效率的替代品,基于 2014 年推出的高效视频编码(HEVC)视频压缩标准的帧内编码
  • HEIF,另一种基于 HEVC 的图像格式
  • JPEG XR 是 2009 年推出的支持 HDR 和宽色域空间的 JPEG 2000 的替代品
  • JPEG 2000,一种改进,旨在取代 2000 年推出的 JPEG 委员会的旧 JPEG
  • MNG 和 APNG,基于 PNG 的动画图像格式,支持无损 24 位 RGB 颜色和 8 位 alpha 通道
  • AV1 静止图像文件格式,基于 AV1 视频编解码器的容器格式

如何将图片转化为 webp

官方命令行

(1)WebP 命令行工具安装:
Google 提供了命令行工具用于将图片转换为 webp

brew install webp

(2)使用 cwebp 将图像转换为 WebP 的格式:

/*** 参数可以参考:https://developers.google.com/speed/webp/docs/cwebp
***/
cwebp [options] input_file -o output_file.webp
// 质量参数 q,q 为 0~100 之间的数字,比较典型的质量值大约为 80, 默认 75   
// 在有损压缩(默认)的情况下,较小的因子会产生质量较低的较小文件。// 在无损压缩(由 -lossless 选项指定, 对图像进行编码而不会有任何损失)的情况下,较小的因素可以实现更快的压缩速度,但会产生更大的文件。cwebp -q 80 WechatIMG4.jpeg -o 11.webp
  • 有关编码器,其标准和高级选项的说明,请参考编码文档
  • 输入格式可以是 PNG,JPEG,TIFF,WebP 或原始 Y ’CbCr(有时候也被写作 YCBCR,是色彩空间的一种,通常会用于影片中的影像连续处理,或是数字摄影系统中)样本。

(3)使用 dwebp 从 WebP 的格式转换为 png(默认)图像:

/*** 参数可参考:
https://developers.google.com/speed/webp/docs/dwebp
***/
dwebp in_file [options] [-o out_file]
// -o 指定输出文件的名称(默认为 PNG 格式)dwebp 11.webp -o convertback.png
  • 有关解码器及其命令行选项的说明, 请参考解码文档
  • dwebp 将 WebP 文件解压缩为 PNG,PAM,PPM 或 PGM 图像

(4)gif2webp:将 GIF 图像转换为 WebP

/***
参数参考:https://developers.google.com/speed/webp/docs/gif2webp
***/
gif2webp [options] input_file.gif -o output_file.webp
gif2webp -q 70 phone.gif -o phone.webp

(5)img2webp:从一系列输入图像创建动画 WebP 文件

/***
参数参考:https://developers.google.com/speed/webp/docs/img2webp
***/
/*** 文件级选项 -loop int:指定动画应循环的次数。使用 0 手段 '无限循环'
     -lossless, -lossy:使用无损或有损压缩模式压缩下一个图像。默认模式是无损的
***/
img2webp -loop 0 pddlogo.png -lossy tblogo.png -d 80 -o out11.webp

(6)vwebp:解压缩 WebP 文件并使用 OpenGL 在窗口中显示它

/***
参数参考:https://developers.google.com/speed/webp/docs/vwebp
***/
vwebp [options] input_file.webp

vwebp picture.webp

(7)webpinfo:用于打印出 WebP 文件的块级结构和比特流头信息。它还可以检查文件是否是有效的 WebP 格式

/***
参数参考:https://developers.google.com/speed/webp/docs/webpinfo
***/
webpinfo out11.webp

(8)webpmux:从非动画 WebP 图像创建动画 WebP 文件,从动画 WebP 图像中提取帧,以及管理 XMP / EXIF 元数据和 ICC 配置文件

/***
参考地址:https://developers.google.com/speed/webp/docs/webpmux
***/
// 从动画 WebP 文件中获取第 1 帧
webpmux -get frame 1 out11.webp -o frame_2.webp
// 把获取到的图片转化成 png
dwebp frame_2.webp -o convertbackframe_2.png

相关在线转化工具

  • 智图
  • 又拍云
  • CloudConvert
  • isparta

canvas 生成

var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d'),
    img = document.getElementById('img');

    var loadImg = function(url, fn) {var image = new Image();
        image.src = url;
        image.onload = function() {fn(image);
        }
    }
    loadImg('image url', function(image) {
        canvas.height = image.height;
        canvas.width = image.width;
        ctx.drawImage(image, 0, 0);
        img.setAttribute('src', canvas.toDataURL('image/webp'));
    });

gulp-WebP 或 gulp-imageisux

  1. gulp-WebP
// 有损压缩图片设置 webp 插件的 quality 参数,无损压缩设置 lossless 参数为 true 即可
var gulp = require('gulp');
var webp = require('gulp-webp');

gulp.task('default', ()=> {gulp.src('./*.{png,jpg,jpeg}')
    .pipe(webp({quality: 80}))
    .pipe(gulp.dest('./dist'));
});
  1. gulp-imageisux
/***
dirpath 目标目录: 如果未定义,会自动生成两个目录:'/dest/' 目录放压缩后图片,'/webp/' 目录放对应的 webp 格式压缩图片
enableWebp 是否同时导出对应 WEBP 格式图片:若为 true,则会同时输出 webp 图片;若为 false,则只会有压缩后原格式图片
***/
var imageisux = require('gulp-imageisux');

gulp.task('imageisux', function() {return gulp.src(['img/*'])
        .pipe(imageisux('/dirpath/',enableWebp));
});

如何判断浏览器是否支持 webp

  1. HTML5 picture(picture 兼容性


这种方法不进行 WebP 支持程度的判断,而是利用 html5 picture 元素的特性,允许开发者列举出多个图片地址,浏览器根据顺序展示出第一个能够展现的图片元素,如:

// 在浏览器不支持 WebP 图片的情况下自动回退到 jpg 格式进行展示
<picture>
    <source type="image/webp" srcset="images/webp.webp">
    <img src="images/webp.jpg" alt="webp image">
</picture>
  1. 嗅探

是指直接向浏览器中插入一段 base64 的 WebP 图片,检测图片是否能够正常加载,依据该方法进而判断支持程度,如官方给出的嗅探函数:

// check_webp_feature:
//   'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
//   'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

其中包含了对有损、无损、透明图、动图等 WebP 图片的嗅探,这是一种最为保险的方法。不过缺点也很明显,在图片类型不一且量级较大的情况下,前端并不能知道哪些图片是有损,无损,亦或是透明的,也没有办法对其中一种特定类型做特定策略,所以即使知道不支持该类型的 WebP,然而我们也没有办法主观的去做容错。所以这种方法只适合于图片类型单一的情况,如开发者知道所有图片都是有损的,或是动图等,有针对性的去处理。
同时在处理的过程中,为了提高嗅探效率,嗅探之后可以将结果以本地存储的方式进行保存,如 cookie,方便下次直接进行调用

  1. Request Header:是较为符合标准的解决方案

浏览器在支持 WebP 图片格式的情况下,会在请求的 http header accept 中携带 webp/image 的字段,后端接收到请求之后可以按照该形式来判断是否返回 WebP 图片内容;
坑——国内浏览器层出不群,大部分都向标准化的方向靠近,但仍然需要一定的时间来跟进。所以,在实践过程中我们就发现了这样的问题:虽然 http header accept 中包含了 webp/image 的字段,但实际上是不支持 WebP 格式的(华为 MT7 自带浏览器),具体体现在动图(animation)的 feature 上。而相应的解决方案如下:

<img src="./img/out11.webp" alt="webp image"
    onerror="javascript:this.src='./img/WechatIMG4.jpeg'">
  • 预先存储:直接把图片转化成 webp 格式的 放到项目目录里面,页面上直接请求 webp 的图片格式,这时候服务器只需要配置 nginx 对 webp 格式支持就好;
  • 实时转换:我们项目目录里面放 png 的图片,比如 1.png,页面访问 1.png.webp,这时候需要 nginx 对域名进行拦截,lua 脚本进行域名后缀规则的匹配,比如说 300×300.png/.webp 类似的后缀,匹配完成后再在 lua 里调用 graphicsmagick 的命令,进行一些图片转换、裁剪等工作,此方案转化过程较慢

附加:

针对不支持 webp 的可以参考:
http://webpjs.appspot.com/

总结

WebP 作为一种新型图片格式,不但能够节省流量,减少图片体积,一定程度上也可以优化用户体验,越来越多的浏览器都开始支持使用,但是根据不同的场景和需求,使用需要谨慎。

正文完
 0