我的项目中的动态图片,个别有两种应用形式:

  • 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-devnpm 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 14Safari 14 公布之后,就能反对WebP了
  • 除Safari之外,PC浏览器根本都反对

总结

WebP格局是图片的一大改革,以往的一张500K的PNG的图片,转换成WebP之后,只有50K左右,压缩比例高达90%。

再者,随着 iOS 14 的行将公布,WebP的挪动端支持率将达到90%以上。

尽早将WebP用起来,也能为你的用户省去一大笔流量,让你的页面关上更快。