图片的加载,一直是网页应用的优化项之一。

 

想要提升网页对于图片的加载速度,最有效的方式就是减少图片体积,这就要用到图片压缩技术。

 

常见的图片格式有:jpg、png、webp等。其中jpg为有损压缩,png为无损压缩,webp同时支持无损、有损压缩。webP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量。

 

nodejs puppeteer 压缩 node压缩图片_图片压缩

 

因此图片压缩技术选型优先考虑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测试

 

样图为手机拍摄的一张照片

 

nodejs puppeteer 压缩 node压缩图片_加载_02

nodejs puppeteer 压缩 node压缩图片_图片压缩_03

nodejs puppeteer 压缩 node压缩图片_nodejs puppeteer 压缩_04

nodejs puppeteer 压缩 node压缩图片_图片压缩_05

压缩比为8.65!体积竟减少了88.4%!

5

细节保留情况

 

在花瓣上有一根蜘蛛丝

 

原图放大100%

nodejs puppeteer 压缩 node压缩图片_加载_06

 

webp图放大100%

nodejs puppeteer 压缩 node压缩图片_图片压缩_07

 

肉眼几乎看不出差别。

 

原图放大800%

nodejs puppeteer 压缩 node压缩图片_nodejs puppeteer 压缩_08

 

webp图放大800%

nodejs puppeteer 压缩 node压缩图片_加载_09

 

webp图略有模糊,细节相对较少。但这种差别已经是可以忽略不计的了。甚至webp的损率还可以继续提高:50%,甚至90%!

 

损率50%:

 

plugins: [imageminWebp({ quality: 50 })],

 

nodejs puppeteer 压缩 node压缩图片_加载_10

100%放大图

nodejs puppeteer 压缩 node压缩图片_图片压缩_11

800%放大图

nodejs puppeteer 压缩 node压缩图片_nodejs puppeteer 压缩_12

 

损率90%

 

plugins: [imageminWebp({ quality: 10 })],

 

nodejs puppeteer 压缩 node压缩图片_图片压缩_13

100%放大图

nodejs puppeteer 压缩 node压缩图片_数据_14

800%放大图

nodejs puppeteer 压缩 node压缩图片_图片压缩_15

 

90%的损率才能较为明显的看出差别,真的佩服webp的压缩技术。

6

格式兼容

 

webp格式的图片在主流浏览器中的兼容程度:

 

nodejs puppeteer 压缩 node压缩图片_图片压缩_16

 

在Safari浏览器支持程度不高,且小程序中不支持。为了解决这一问题,使用另外一种图片解析方式。

 

在webp压缩后返回了该文件的buffer数据流:

 

nodejs puppeteer 压缩 node压缩图片_图片压缩_17

 

buffer数据流又可以转换为base64格式的数据,而base64格式的数据img标签自动可以解析,只需要在头部加上:  

 

data:image/[jpg|png|webp|...];base64,

 

如:

nodejs puppeteer 压缩 node压缩图片_图片压缩_18

 

即使是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",
  });
});

 

nodejs puppeteer 压缩 node压缩图片_加载_19

 

网页打开:

nodejs puppeteer 压缩 node压缩图片_nodejs puppeteer 压缩_20

 

规避了格式兼容问题,提高了加载速度,节省了存储资源及网络带宽资源,完美!

 

nodejs puppeteer 压缩 node压缩图片_加载_21