项目中的静态图片,一般有两种使用方式:
- HTML中的
标签
- CSS中的
background-image
属性
尽可能的使用CSS的方式去加载图片,当然如果你依赖图片本身的宽高等比缩放的特性,还是使HTML的方式。
框架
本文将以vue-cli 3.0脚手架搭建的项目为例。
转换工具
我们选择的是 Imagemin
,版本选择6.1.0,因为7.0.0之后的版本在windows上有兼容性问题,目前还未修复。
npm install [email protected] --save-dev
npm install imagemin-webp --save-dev
转换脚本
我们的转换脚本需要支持全量转换,单个目录转换,以及单文件转换三种模式,质量默认选择75,实际测下来发现,75的质量跟100的质量肉眼基本看不出来区别,以下是脚本代码的实现:
/**
* 脚本位于tools目录,即 ./tools/webp.js
* 项目的源码均位于src目录,即 ./src/
* 可以自行调整代码中的部分目录配置
*/
const imageMin = require('imagemin')
const imageMinWebp = require('imagemin-webp')
const path = require('path')
const fs = require('fs')
let quality = 75
// 根据自身项目调整
let rootDir = path.join(__dirname, '../src')
async function loop (dir) {
await imageMin([path.join(dir, '*.{jpg,png}')], dir, {
plugins: [
imageMinWebp({
quality: quality
})
]
})
console.log(dir)
let res = fs.readdirSync(dir, {
withFileTypes: true
})
for (let i = 0, length = res.length; i < length; i++) {
if (res[i].isDirectory()) {
await loop(path.join(dir, res[i].name))
}
}
}
if (process.argv.length >= 3) {
if (process.argv[3]) {
quality = process.argv[3]
}
// 根据自身项目调整
let dir = path.join(__dirname, '../', process.argv[2])
const stats = fs.statSync(dir)
if (stats.isDirectory()) {
rootDir = dir
await loop(rootDir)
console.log('completed!')
} else if (stats.isFile()) {
await imageMin([dir], path.dirname(dir), {
plugins: [
imageMinWebp({
quality: quality
})
]
})
console.log(dir)
console.log('completed!')
}
} else {
await loop(rootDir)
console.log('completed!')
}
转换全部图片:
node ./tools/webp.js
转换 src/components
目录下的全部图片:
node ./tools/webp.js src/components
转换单个图片文件 src/images/picture.png
:
node ./tools/webp.js src/images/picture.png
转换全部图片,并设置转换质量为100:
node ./tools/webp.js src 100
检测是否支持
https://modernizr.com/downloa...
打开上面的链接,点BUILD,即可下载
有以下两种引入方式:
- Es6 Module: 通过import引入
- Inline Push(内联脚本): 通过将代码放在
标签中引入
Es6 Module
适合纯前端渲染的架构,如Vue,React,Angular等。这种架构在JS执行之前,页面上没有图片内容,所以不用考虑 FOUC
(Flash of Unstyled Content) 的情况。
Inline Push(内联脚本)
适合后端渲染的架构,如PHP,Nodejs等。这种架构下,页面上可能已经有了图片,所以必须将 Inline Script 放在 中,并且位于所有
和
标签之后,一方面让js可以尽快执行,另一方面可以避免出现
FOUC
的情况。
HTML中使用
Vue框架中,可以在js里面判断:
CSS中使用
用SCSS预编译语言:
.picture {
background-image:url(picture.png);
.webp & {
background-image:url(picture.webp);
}
}
边界问题
使用Es6 Module方式引入的时候,如果需要立刻判断是否支持,需要依赖监听函数,因为检测是需要消耗一定的时间,如下:
window.Modernizr.on('webp', (result) => {
if (result) {
// support
} else {
// not support
}
})
兼容性
- 安卓基本都支持
- 苹果全部不支持,等
iOS 14
和Safari 14
发布之后,就能支持WebP了 - 除Safari之外,PC浏览器基本都支持
总结
WebP格式是图片的一大变革,以往的一张500K的PNG的图片,转换成WebP之后,只有50K左右,压缩比例高达90%。
再者,随着 iOS 14
的即将发布,WebP的移动端支持率将达到90%以上。
尽早将WebP用起来,也能为你的用户省去一大笔流量,让你的页面打开更快。