Skip to content

webp H5移动端实战总结 #7

Description

@liveKang

webp H5移动端实战总结

Isabella Scherer

对于移动端优化来说,图片大小是不可忽视的一部分,png, jpg, jpeg, gif, sprites, PS 先导出 web 格式压缩品质,前端构建工具压缩,服务端对图片进行再次压缩,甚至采用某某小道的极致压缩等等,都没能达到期望的效果。为此 webp(谷歌官方地址) 实战部署的想法,应运而生。

解决方案

方案一

服务端根据浏览器Request Headers中的Accept 判断是否有 image/webp,有则代表该浏览器支持webp格式的图片,无则不支持,返回原图,适用于整站图片处理。难点在运维同学需要处理下。前端同学给大佬送茶即可。

方案二

服务端根据图片的请求尾缀生成 webp 。

首先前端检测该浏览器是否支持 webp 。

方法比较多,这边列举一种加载一个小 webp 图片的方案。

var img = new Image();
img.onload = function () {
    var result = (img.width > 0) && (img.height > 0);
    console.log("当前浏览器支持webp");
};
img.onerror = function () {
    console.log("当前浏览器不支持webp");
};
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';

例如一张原图地址https://m.pinhui001.com/dist_css/img/index-foreign.jpg,如果浏览器支持webp,则在图片的后面加上.webp的尾缀。如https://m.pinhui001.com/dist_css/img/index-foreign.jpg.webp,反之则不加。这种方案是由前端控制是否需要 webp 格式图片,需要就由服务端生成,每张图片第一次访问时会立即生成一张 webp 图片。会需要一定的生成时间。

我们使用的是nginx容器发布。可以采用 Nginx-Lua 自动转换图片为 WEBP 格式。

  1. 安装 libwebp

    通过包管理安装 libwebp

    pacman -S libwebp

    手动安装

    wget "http://downloads.webmproject.org/releases/webp/libwebp-0.5.0-linux-x86-64.tar.gz" tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local

    这样我们就会有了 libwebp 和 "cwebp" 命令来方便的编码图片

  2. lua代码

     function file_exists(name)
        local f=io.open(name,"r")
        if f~=nil then io.close(f) return true else return false end
     end
     
     local newFile = ngx.var.request_filename;
     local originalFile = newFile:sub(1, #newFile - 5); -- 去掉 .webp 的后缀
     
     if not file_exists(originalFile) then -- 原文件不存在
       ngx.exit(404);
       return;
     end
     
     os.execute("cwebp -q 75 " .. originalFile  .. " -o " .. newFile);   -- 转换原图片到 webp 格式,这里的质量是 75 ,你也可以改成别的
     
     if file_exists(newFile) then -- 如果新文件存在(转换成功)
         ngx.exec(ngx.var.uri) -- Internal Redirect
     else
         ngx.exit(404)
     end
     
  3. Nginx 配置

    在Http块中加入

     lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;"; # 指向存放 lua 代码的路径
     

    server 块中加入一个 location

     location /images {
       expires 365d;
       try_files $uri $uri/ @webp; # 如果文件不存在尝试生成 webp 图片
     }
     location @webp{
       if ($uri ~ "/([a-zA-Z0-9-_]+)\.(png|jpg|gif)\.webp") { # 这里可以改成你自己的路径匹配,很重要,否则可能会导致别的文件被恶意覆盖等
         content_by_lua_file "/usr/local/nginx/conf/waf/webp.lua";
       }
     }
     

方案三

公司的图片库动辄几百上千G,如果要全面启用 webp,如果有一定困难的话,我们也是可以局部使用 webp 的,前端自己生成 webp 图片,我们应用的是静态资源部分的图片。这里以 gulp 为例,描述下前端如何生成 webp图片。

gulp 中有一个模块 gulp-webp,该模块依赖了 imagemin-webp。代码如下,比较简单,生成的速度也比较快。与静态资源一并上传到生产就可以使用了。

gulp.task('webp', function() {
    return gulp.src(Config.img.src)
	    .pipe(webp({
	        quality: 75
	    }))
	    .pipe(flatten())
	    .pipe(gulpif(!ifProd,gulp.dest(Config.img.dist)))
	    .pipe(gulpif(ifProd,gulp.dest(Config.img.dist_prod)));
});

总结

移动端流量优化中图片优化,webp带来的优势相当明显。

附录

webp图片适配流量优化(推荐阅读)

对我以上的理解有疑问和意见的欢迎找我私聊~

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions