背景
之前在开发实验室官网(https://www.xiyoumobile.com)的时候,由于图片特别多,学校服务器走电信和教育网,带宽也不够,在某些网络环境图片加载十分缓慢,而且有时候主页打开需要10s+的时间,所以考虑从图片压缩上节省网络带宽
目前业界的图片压缩方案有以下几种,他们的压缩比都很高,都可以有效减小图片文件的体积
|方案|提出者|编码类型|开源|官网|浏览器支持情况|
|——-|——-|——-|——-|——-|
|WebP|Google|VP8|是|https://developers.google.com/speed/webp/|Chrome、Opera、Edge、Android,及其他基于Chromium内核的浏览器|
|BPG|Fabrice Bellard|HEVC|是|http://bellard.org/bpg|无|
|TPG|腾讯|AVS2(类似AVC)|否|未知|QQ浏览器|
|JPEG XR|微软|未知|否|(微软已投奔WebP)|IE、Edge|
根据TPG推出时腾讯的微信公众号文章来看,TPG的压缩算法相比WebP而言,能够使体积变得更小,图片更清晰,但是适用范围还是太局限了,所以还是选择了WebP
但主要问题是前端代码中已经固定了某些静态图片资源的URL及扩展名,数据库中保存的HTML中的图片引用也是如此,即使把图片全部转换为WebP格式,如何保证不改动HTML及CSS代码,就能够对支持的浏览器返回WebP格式图片,而不支持的浏览器返回JPG/PNG?
于是经过一段时间摸索和整理,就有了现在用在我个人网站的coderyuan-image-server:https://github.com/yuanguozheng/coderyuan-image-server
基本原理及流程
判断浏览器是否支持WebP
首先引用一段来自w3的定义(RFC 2616):https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.
Accept = "Accept" ":"
#( media-range [ accept-params ] )
media-range = ( "*/*"
| ( type "/" "*" )
| ( type "/" subtype )
) *( ";" parameter )
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
这里定义了HTTP请求头中Accept字段的含义——表示Response可以接受的媒体类型(MIME-Type)
如果支持WebP,那么Accept中将会包含image/webp
这样的字符串
于是乎,我们就可以根据浏览器请求图片资源时的Accept字段来区分是否真正支持WebP格式
为什么不使用User-Agent?