我的项目中的动态图片,个别有两种应用形式:
- HTML 中的
<img>
标签 - CSS 中的
background-image
属性
尽可能的应用 CSS 的形式去加载图片,当然如果你依赖图片自身的宽低等比缩放的个性,还是使 HTML 的形式。
框架
本文将以 vue-cli 3.0 脚手架搭建的我的项目为例。
转换工具
咱们抉择的是 Imagemin
,版本抉择 6.1.0,因为 7.0.0 之后的版本在 windows 上有兼容性问题,目前还未修复。
npm install imagemin@6.1.0 --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(内联脚本): 通过将代码放在
<head>
标签中引入
Es6 Module
适宜纯前端渲染的架构,如 Vue,React,Angular 等。这种架构在 JS 执行之前,页面上没有图片内容,所以不必思考 FOUC
(Flash of Unstyled Content) 的状况。
Inline Push(内联脚本)
适宜后端渲染的架构,如 PHP,Nodejs 等。这种架构下,页面上可能曾经有了图片,所以必须将 Inline Script 放在 <head>
中,并且位于所有 <style>
和 <link>
标签之后,一方面让 js 能够尽快执行,另一方面能够避免出现 FOUC
的状况。
HTML 中应用
Vue 框架中,能够在 js 外面判断:
<template>
<div class="container">
<img :src="picture">
</div>
</template>
<script>
import picture from 'picture.jpg'
import pictureWebP from 'picture.webp'
export default {data () {
return {picture: window.Modernizr.webp ? pictureWebP : picture}
}
}
</script>
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 用起来,也能为你的用户省去一大笔流量,让你的页面关上更快。