imagemin 是一个图片压缩工具,它提供 CLI 和 npm module 两种使用方式,一般推荐使用 npm module 形式,因为它能提供更多配置选项,也可以嵌入到 webpack
等工具的打包流程中,另外还有一系列配套的插件来处理不同格式的图片文件。
npm install --global imagemin-cli
-
imagemin images/* --out-dir=dist
: 将images
文件夹中的所有图片进行压缩并输出到dist
文件夹中。 -
imagemin --help
: 查看所有配置选项。
Usage
$ imagemin <path|glob> ... --out-dir=build [--plugin=<name> ...]
$ imagemin <file> > <output>
$ cat <file> | imagemin > <output>
Options
--plugin, -p Override the default plugins
--out-dir, -o Output directory
Examples
$ imagemin images/* --out-dir=build
$ imagemin foo.png > foo-optimized.png
$ cat foo.png | imagemin > foo-optimized.png
$ imagemin foo.png --plugin=pngquant > foo-optimized.png
$ imagemin foo.png --plugin.pngquant.quality={0.1,0.2} > foo-optimized.png
$ imagemin foo.png --plugin.webp.quality=95 --plugin.webp.preset=icon > foo-icon.webp
npm i -D imagemin
- Node script
e.g. 使用
imagemin-mozjpeg
插件来压缩jpeg
图片
const imagemin = require('imagemin')
const imageminMozjpeg = require('imagemin-mozjpeg')
imagemin(
// 指定需要压缩的图片文件路径
['images/*.jpg'],
{
// 指定压缩后图片文件的输出路径
destination: 'dist/images',
// 指定负责处理图片的插件
plugins: [imageminMozjpeg({ quality: 50 })]
}
)
e.g. webpack.config.js
// 引入 imagemin-webpack-plugin
const ImageminPlugin = require('imagemin-webpack-plugin')
// 如果想要自己指定处理图片的插件,也需要另外引入
const imageminMozjpeg = require('imagemin-mozjpeg')
module.exports = {
plugins: [
ImageminPlugin({
// pngquant 是 imagemin-webpack-plugin 使用的默认插件之一
// 所以可以直接指定配置选项
pngquant: { quality: [0.5, 0.5] },
// imagemin-mozjpeg 不是 imagemin-webpack-plugin 的默认插件
// 所以需要额外引入并加入到 plugins 数组中
plugins: [imageminMozjpeg({ quality: 50 })]
})
]
}
图片格式 | 有损 | 无损 |
---|---|---|
JPEG | imagemin-mozjpeg | imagemin-jpegtran |
PNG | imagemin-pngquant | imagemin-optipng |
GIF | imagemin-giflossy | imagemin-gifsicle |
SVG | imagemin-svgo | |
WebP | imagemin-webp |
tips: 如果一个插件提供订制图片质量的配置选项,那它就是一个有损压缩的插件。
有些 GIF 的体积可能会很大,将它们转换成视频格式可以节省用户带宽。
FFmpeg 是一个音频/视频转换工具,使用方法如下:
- 去官网上下载,官网也提供了很详细的使用文档。
- 使用 npm module,这种方法也需要先安装 FFmpeg。
将 GIF 文件转换成视频之后,还需要在文档中进行替换。
GIF 有三个特点:
- 自动播放
- 无限循环
- 静音
这些都可以通过 video
标签的属性来设置:
<video autoplay loop muted playsinline></video>
还可以通过 <source>
元素来提供 fallback:
<video autoplay loop muted playsinline>
<source src="my-animation.webm" type="video/webm" />
<source src="my-animation.mp4" type="video/mp4" />
</video>
给不同设备提供不同尺寸的图片,比较常用的两个用来生成不同尺寸图片的工具是 sharp 和 ImageMagick CLI:
sharp 是一个 npm 包
npm i -D sharp
Node script
const sharp = require('sharp')
const fs = require('fs')
const directory = './images'
fs.readdirSync(directory).forEach((file) => {
const format = /.*\.([a-zA-Z]+)/.exec(file)[1]
sharp(`${directory}/${file}`)
.resize(200, 100) // width, height
.toFile(`${directory}/${file}-small.${format}`)
})
ImageMagick 是一个 CLI 工具
去官网下载安装包。
- 命令行,不过有平台兼容性问题。
例子 1 convert -resize 33% logo.jpg logo-small.jpg
:将 logo.jpg
转换成原图的三分一大小。
例子 2 convert logo.jpg -resize 300x200 logo-small.jpg
:将图片尺寸调整为 300x200
- 也可以下载 imagemagick-cli npm 包,然后通过 Node 来调用,这个包解决了操作系统兼容性的问题。
Node script
const imagemagickCli = require('imagemagick-cli')
imagemagickCli.exec('convert -version')
每张图片应该有多少种尺寸?这个问题没有统一答案,不过比较常见的是 3-5 种。
将图片转换成不同的尺寸后,还需要在 HTML 中为不同屏幕尺寸指定不同版本的图片,然后浏览器就会根据实际情况来选择加载哪张图片。
<img src="logo.jpg" srcset="logo-small.jpg 480w, logo-large.jpg 1080w" sizes="50vw" />
src
是为了兼容那些不支持srcset
和sizes
属性的浏览器。logo-small.jpg 480w
表示logo-small.jpg
这张图的宽度是480px
,这样浏览器就不用等把图片下载完后才知道图片的尺寸。注意到图片宽度的单位是px
,但在设置时要写成w
,关于 width descriptor。sizes
属性告诉浏览器图片在页面上显示时的宽度,但是设置这个属性对图片的显示效果并没有影响(我们还是得设置 CSS),这个值只是用来帮助浏览器决定应该加载哪张图片,如果没有这个属性,浏览器就会加载src
属性中指定的图片。sizes
的有效值包括100px
,33vw
,20em
,calc(50vw-10px)
,但是百分比25%
是不合法的。
srcset 和 sizes 属性是配合使用的。
art direction: 在不同大小的屏幕中显示内容不同的图片,而不仅仅是尺寸不同的图片。
两个常用的将图片转换成 WebP 的工具是:cwebp CLI 工具 和 Imagemin WebP 插件,一般推荐使用 Imagemin WebP 插件,因为可以整合到打包工具中。
转换单张图片,使用默认配置:
cwebp images/flower.jpg -o images/flower.webp
转换单张图片,设置 quality 为 50:
cwebp -q 50 images/flower.jpg -o images/flower.webp
转换指定文件夹中的所有图片:
for file in images/*; do cwebp "$file" -o "${file%.*}.webp"; done
npm install imagemin-webp
- Node script:
const imagemin = require('imagemin')
const imageminWebp = require('imagemin-webp)
imagemin(
['images/*.{jpg,png}'],
{
destination: 'build/images',
plugins: [
imageminWebp({quality: 50})
]
}
)
如果需要兼容不支持 WebP 的浏览器的话,还需要提供 fallback 文件。
<picture>
<source type="image/webp" srcset="flower.webp" />
<source type="image/jpeg" srcset="flower.jpg" />
<img src="flower.jpg" alt="" />
</picture>
<picture>
中可以指定多个<source>
,按优先级排列。<img>
是为了兼容不支持<picture>
标签的浏览器。