图片的加载,一直是网页应用的优化项之一。
想要提升网页对于图片的加载速度,最有效的方式就是减少图片体积,这就要用到图片压缩技术。
常见的图片格式有:jpg、png、webp等。其中jpg为有损压缩,png为无损压缩,webp同时支持无损、有损压缩。webP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量。
因此图片压缩技术选型优先考虑webp技术,在node中有一个包:
imagemin
专门用来做图片压缩,其中:
imagemin-webp
是利用webp技术压缩图片。
1
安装依赖包
npm i imagemin imagemin-webp --save
2
webp压缩
const imagemin = require("imagemin");
const imageminWebp = require("imagemin-webp");
const compImg = async function (file) {
let compfile = await imagemin([`public/images/${file}`], {
destination: "public/compressed-images",
plugins: [imageminWebp({ quality: 75 })],// 压缩质量75%
});
return compfile;
};
module.exports = compImg;
3
编写图片上传接口
var express = require("express");
var router = express.Router();
var multer = require("multer");
const path = require("path");
const compImg = require("../src/comp"); // 引入comp.js的压缩函数
let filename = "";
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/images");
},
filename: function (req, file, cb) {
let exname = path.extname(file.originalname);
filename = file.fieldname + "-" + Date.now() + exname;
cb(null, filename);
},
});
var upload = multer({ storage: storage });
router.post("/webp/compImg", upload.single("file"), async (req, res, next) => {
let compfile = await compImg(filename);
res.send({
code: 200,
data: compfile ,
msg: "ok",
});
});
module.exports = router;
4
postman测试
样图为手机拍摄的一张照片
压缩比为8.65!体积竟减少了88.4%!
5
细节保留情况
在花瓣上有一根蜘蛛丝
原图放大100%
webp图放大100%
肉眼几乎看不出差别。
原图放大800%
webp图放大800%
webp图略有模糊,细节相对较少。但这种差别已经是可以忽略不计的了。甚至webp的损率还可以继续提高:50%,甚至90%!
损率50%:
plugins: [imageminWebp({ quality: 50 })],
100%放大图
800%放大图
损率90%
plugins: [imageminWebp({ quality: 10 })],
100%放大图
800%放大图
90%的损率才能较为明显的看出差别,真的佩服webp的压缩技术。
6
格式兼容
webp格式的图片在主流浏览器中的兼容程度:
在Safari浏览器支持程度不高,且小程序中不支持。为了解决这一问题,使用另外一种图片解析方式。
在webp压缩后返回了该文件的buffer数据流:
buffer数据流又可以转换为base64格式的数据,而base64格式的数据img标签自动可以解析,只需要在头部加上:
data:image/[jpg|png|webp|...];base64,
如:
即使是webp方式压缩后的base64数据也可以使用其他格式解析,并不冲突。
router.post("/webp/compImg", upload.single("file"), async (req, res, next) => {
let compfile = await compImg(filename);
let data = [];
compfile.map(el => {
let buffer = Buffer.from(el.data, "utf-8");
let base64Str = buffer.toString("base64");
console.log(compfile);
return data.push(base64Str);
});
res.send({
code: 200,
data,
msg: "ok",
});
});
网页打开:
规避了格式兼容问题,提高了加载速度,节省了存储资源及网络带宽资源,完美!