苦逼前端

开发无感知的webp升级方案

Javascript2019-03-17 19:51

webp最早由Google收购的On2 Technologies于2010年9月底提出,2014年初发布的Chrome@32和稍早发布的Android Browser@4.2完全支持了webp的所有特性,包括有损压缩、无损压缩、动态图等,然而直到现在Apple生态还是完全不支持webp,包括iOS Safari和pc Safari。虽然如此,我相信终有一天它会被广泛接受,毕竟无损压缩可以减少普通png图片体积的45%,jpg图片的30%,详细对比请看这里

升级方案主要有两步,第一步是判断客户端支持程度,判断支持程度有两种方法:
第一种是前端判断环境,根据支持程度选择使用webp链接或png链接(或是使用picture标签,但无法作为背景图使用)
第二种是服务端判断环境,根据request header中的Accept中有无image/webp来判断

第二步是生成webp格式图片,方法也有两种: 第一种是前端生成,在各种构建工具泛滥的时代,前端构建打包的同时输出一份同名但是以.webp后缀结尾的webp格式的文件(a.png => a.png.webp)简直是小菜一碟
第二种是服务端生成(这是废话,也没有第三端了)

既然要开发无感,又要考虑到服务端成本,所以最终选择了在Nginx中检测环境,然后前端构建工具生成同名webp格式图片的方案

Nginx相关配置:

map $http_accept $webp_suffix {
    default   "";
    "~*webp"  ".webp";
}

server {
    listen 80;
    server_name: 127.0.0.1;
    location ~* ^.+\.(jpe?g|png)$ {
        root /static/root;
        add_header Vary Accept;
        try_files $uri$webp_suffix $uri =404;
        expires 30d;
    }
}

webpack相关配置:

const ImageminWebpWebpackPlugin = require('imagemin-webp-webpack-plugin');

return {
    plugins: [
        new ImageminWebpWebpackPlugin({
            config: [{
                test: /\.(jpe?g|png)$/,
                options: {
                    quality: 60,
                }
            }],
            overrideExtension: false,
            detailedLogs: true,
            strict: false
        })
    ]
};

这样,当某个图片请求到达服务器时,存在三种情况,比如说是a.png:

  1. 浏览器不支持webp格式图片,则$webp_suffix取默认的无后缀,直接返回a.png
  2. 浏览器支持webp格式图片,但服务器上并没有a.png.webp,则仍然返回a.png
  3. 浏览器支持webp格式图片,并且服务器上也有a.png.webp,则会返回a.png.webp

这么做还存在几个小问题:

  1. 假如某浏览器请求头中的Accept中含有image/webp,但实际却并不支持webp格式的图片,那明显是要出事的,好在目前还没遇到这种浏览器
  2. 前端构建工具生成同名webp格式图片,但一些运营配的在线图片可能并没有同名的webp格式图片,所以要定好规范,手动配的图片也需要配一份同名的webp格式的图片
评论(2)
  • 114.255.247.*: 大神!!牛皮1年2个月前
  • 123.119.143.*: 大神,牛皮~4个月前
还可输入200个字