[TOC]
0x00 快速入门 WebP 介绍 什么是 WebP? WebP是由Google推出的一种全新图片文件格式,也是Telegram Stickers 主力使用的文件格式,可为 Web 上的图像提供卓越的无损和有损压缩, 它是在保证原有的图像质量前提下尽可能减少图形体积的一种格式, 使用WebP网站管理员和 Web 开发人员可以创建更小、更丰富的图像,从而使 Web 加载性能的提升更快。
WebP的有损压缩算法是基于VP8视频格式的帧内编码,并以RIFF作为容器格式。 因此,它是一个具有八位色彩深度和以1:2的比例进行色度子采样的亮度-色度模型(YCbCr 4:2:0)的基于块的转换方案。不含内容的情况下,RIFF容器要求只需20字节的开销,依然能保存额外的元数据(metadata)。
WebP图像的边长限制为16383像素。
在 WebP 的官网中,我们可以发现 Google 是这样宣传 WebP 的:WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index
.(与 PNG 相比,WebP 无损图像的大小要小 26%。在同等 SSIM 质量指数下,WebP 有损图像比可比较的 JPEG 图像小 25-34%)
通过是否对图片进行压缩,我们可以分为:
无压缩。不对图片数据进行压缩处理,能准确地呈现原图片。 BMP 格式就是其中之一。
无损压缩。压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的尺寸。 png 是其中的代表。
有损压缩。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的尺寸。 其中的代表是 jpg。
简单来说,WebP 图片格式的存在,让我们在 WebP 上展示的图片体积可以有较大幅度的缩小,也就带来了加载性能的提升。
如何创建(转换)一个webp格式图片?
要生成一个 WebP 图片非常简单,只需要下载 Google 提供的 cwebp 工具,并且使用 cwebp -q 70 picture_with_alpha.png -o picture_with_alpha.webp
命令就可以转换了, 并且转换出来的 webp 图片比原图会小不少,但是这个是单张图片,我们的目的是让站点的图片可以无痛地以 WebP 格式输出,如果我们的博客上有 100+ 张图片转换该如何操作呢?如果是更多呢?
需求背景 那么开发人员如何优雅的在不替换图片地址的情况下,将图片转为 webp 格式然后输出呢?
答: 此时可以使用 webp-sh 组织最新开源的 webp_server_go 项目,其原理是当我们请求一张图片的时候使用 web 代理工具转发到 webp_server_go 应用进行处理,处理完成之后返回 webp 格式的图片,并且会保留处理后的图片以供后面的 Nginx Web访问。
Webp-Server 介绍 Webp-Server 描述: WebP-Server工具,可将您的 JPG/PNG (有损压缩与无损压缩以及常用图片格式) 即时压缩为 WebP 格式,非常高效可以大幅度的减少图片体积,减少出口带宽,提高用户体验。目前支持的图片格式:JPEG、PNG、BMP、GIF(暂时为静态图片。
例如,使用Webp-Server并争取配置号Nginx代理后,当你访问 https://weiyigeek.top/1.jpg
时,它将作为 image/webp ,而不会更改 URL, 但对于 Safari 用户,将使用原始图像。
weiyigeek.top-VS WebP-Server
支持多开发语言 描述: 其实 webp server 有多种语言都实现了,并且这些仓库还都放在了 webp-sh 该 Organizations 下, 但是对于当下Go语言在编程开发语言中流行程度,官方也非常建议使用go开发的webp-server版本,并且其支持多个webp-server Feature。
Tips: WebP Server is under the GPLv3.
webp_server_go - 主要更新仓库 当前版本 (WebP Server Go 0.4.5) webp_server_node - 最后更新 2020 年 7 月 6 日 webp_server_java - 最后更新 2020 年 3 月 6 日 webp_server_python - 最后更新时间 2020 年 3 月 2 日
温馨提示: 不同版本之间的比较参考地址https://docs.webp.sh/comparisons .
Webp-server 的当前问题?
Safari doesn’t support it. 不支持 Safari。
Tons of Nginx and JavaScript works. 工作需要依赖于Nginx与JavaScript。
It need a tool to transfer. 它需要一个工具来传输。
mod_pagespeed is not easy to use. mod_pagespeed 不好用。
学习参考 官网地址: https://webp.sh 文档说明: https://docs.webp.sh/ 项目地址: https://github.com/webp-sh/webp_server_go 下载地址: https://github.com/webp-sh/webp_server_go/releases/ WebP Cloud Services:https://webp.se/we
0x01 安装实践 二进制安装部署 描述: 此处采用 WebP 服务器的 Go 版本进行实践,此时我已经进行了Nginx的安装配置, 如没有你还安装配置安全的Nginx的读者可以浏览此篇入门文章【1.Nginx基础介绍与安装配置实践指南 - https://blog.weiyigeek.top/2019/9-1-121.html 】进行学习。
快速部署 Step 1.获取 WebP server-Go 版本的二进制方式进行安装。
[TOC]
0x00 快速入门 WebP 介绍 什么是 WebP? WebP是由Google推出的一种全新图片文件格式,也是Telegram Stickers 主力使用的文件格式,可为 Web 上的图像提供卓越的无损和有损压缩, 它是在保证原有的图像质量前提下尽可能减少图形体积的一种格式, 使用WebP网站管理员和 Web 开发人员可以创建更小、更丰富的图像,从而使 Web 加载性能的提升更快。
WebP的有损压缩算法是基于VP8视频格式的帧内编码,并以RIFF作为容器格式。 因此,它是一个具有八位色彩深度和以1:2的比例进行色度子采样的亮度-色度模型(YCbCr 4:2:0)的基于块的转换方案。不含内容的情况下,RIFF容器要求只需20字节的开销,依然能保存额外的元数据(metadata)。
WebP图像的边长限制为16383像素。
在 WebP 的官网中,我们可以发现 Google 是这样宣传 WebP 的:WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index
.(与 PNG 相比,WebP 无损图像的大小要小 26%。在同等 SSIM 质量指数下,WebP 有损图像比可比较的 JPEG 图像小 25-34%)
通过是否对图片进行压缩,我们可以分为:
无压缩。不对图片数据进行压缩处理,能准确地呈现原图片。 BMP 格式就是其中之一。
无损压缩。压缩算法对图片的所有的数据进行编码压缩,能在保证图片的质量的同时降低图片的尺寸。 png 是其中的代表。
有损压缩。压缩算法不会对图片所有的数据进行编码压缩,而是在压缩的时候,去除了人眼无法识别的图片细节。因此有损压缩可以在同等图片质量的情况下大幅降低图片的尺寸。 其中的代表是 jpg。
简单来说,WebP 图片格式的存在,让我们在 WebP 上展示的图片体积可以有较大幅度的缩小,也就带来了加载性能的提升。
如何创建(转换)一个webp格式图片?
要生成一个 WebP 图片非常简单,只需要下载 Google 提供的 cwebp 工具,并且使用 cwebp -q 70 picture_with_alpha.png -o picture_with_alpha.webp
命令就可以转换了, 并且转换出来的 webp 图片比原图会小不少,但是这个是单张图片,我们的目的是让站点的图片可以无痛地以 WebP 格式输出,如果我们的博客上有 100+ 张图片转换该如何操作呢?如果是更多呢?
需求背景 那么开发人员如何优雅的在不替换图片地址的情况下,将图片转为 webp 格式然后输出呢?
答: 此时可以使用 webp-sh 组织最新开源的 webp_server_go 项目,其原理是当我们请求一张图片的时候使用 web 代理工具转发到 webp_server_go 应用进行处理,处理完成之后返回 webp 格式的图片,并且会保留处理后的图片以供后面的 Nginx Web访问。
Webp-Server 介绍 Webp-Server 描述: WebP-Server工具,可将您的 JPG/PNG (有损压缩与无损压缩以及常用图片格式) 即时压缩为 WebP 格式,非常高效可以大幅度的减少图片体积,减少出口带宽,提高用户体验。目前支持的图片格式:JPEG、PNG、BMP、GIF(暂时为静态图片。
例如,使用Webp-Server并争取配置号Nginx代理后,当你访问 https://weiyigeek.top/1.jpg
时,它将作为 image/webp ,而不会更改 URL, 但对于 Safari 用户,将使用原始图像。
weiyigeek.top-VS WebP-Server
支持多开发语言 描述: 其实 webp server 有多种语言都实现了,并且这些仓库还都放在了 webp-sh 该 Organizations 下, 但是对于当下Go语言在编程开发语言中流行程度,官方也非常建议使用go开发的webp-server版本,并且其支持多个webp-server Feature。
Tips: WebP Server is under the GPLv3.
webp_server_go - 主要更新仓库 当前版本 (WebP Server Go 0.4.5) webp_server_node - 最后更新 2020 年 7 月 6 日 webp_server_java - 最后更新 2020 年 3 月 6 日 webp_server_python - 最后更新时间 2020 年 3 月 2 日
温馨提示: 不同版本之间的比较参考地址https://docs.webp.sh/comparisons .
Webp-server 的当前问题?
Safari doesn’t support it. 不支持 Safari。
Tons of Nginx and JavaScript works. 工作需要依赖于Nginx与JavaScript。
It need a tool to transfer. 它需要一个工具来传输。
mod_pagespeed is not easy to use. mod_pagespeed 不好用。
学习参考 官网地址: https://webp.sh 文档说明: https://docs.webp.sh/ 项目地址: https://github.com/webp-sh/webp_server_go 下载地址: https://github.com/webp-sh/webp_server_go/releases/ WebP Cloud Services:https://webp.se/we
0x01 安装实践 二进制安装部署 描述: 此处采用 WebP 服务器的 Go 版本进行实践,此时我已经进行了Nginx的安装配置, 如没有你还安装配置安全的Nginx的读者可以浏览此篇入门文章【1.Nginx基础介绍与安装配置实践指南 - https://blog.weiyigeek.top/2019/9-1-121.html 】进行学习。
快速部署 Step 1.获取 WebP server-Go 版本的二进制方式进行安装。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 INSTALL_HOME=/opt/webps WEBP_HOST=127.0.0.1 WEBP_PORT=3333 WEBP_QUALITY=80 IMG_PATH=/usr/share/nginx/html EXHAUST_PATH=${INSTALL_HOME} /cache if [ -f /usr/bin/apt ];then apt install libaom-dev -y ln -s /usr/lib/x86_64-linux-gnu/libaom.so /usr/lib/x86_64-linux-gnu/libaom.so.3 fi if [ -f /usr/bin/yum ];then yum install libaom-devel -y fi mkdir -vp ${INSTALL_HOME} /cache wget --no-check-certificate https://github.com/webp-sh/webp_server_go/releases/download/0.4.5/webp-server-linux-amd64-80aa8cb63a85a986f83a88579e8d2b4b -O ${INSTALL_HOME} /webp-server chmod +x ${INSTALL_HOME} /webp-server ln -s ${INSTALL_HOME} /webp-server /usr/local /bin/webp-server /usr/local /bin/webp-server -dump-config > ${INSTALL_HOME} /config.json sed -i -e "s#127.0.0.1#${WEBP_HOST} #" \ -e "s#3333#${WEBP_PORT} #" \ -e "s#80#${WEBP_QUALITY} #" \ -e "s#./pics#${IMG_PATH} #" \ -e "s#./exhaust#${EXHAUST_PATH} #" ${INSTALL_HOME} /config.json ${INSTALL_HOME} /webp-server --config=${INSTALL_HOME} /config.json
使用参数一览:1 2 3 4 5 6 7 8 9 webp-server --help Usage of webp-server: -V Show version information. -config string /path/to/config.json. (Default: ./config.json) (default "config.json" ) -dump-config Print sample config.json -dump-systemd Print sample systemd service file. -jobs int Prefetch thread, default is all. (default 2) -prefetch Prefetch and convert image to webp -v Verbose, print out debug info.
weiyigeek.top-Start webp-server 服务
温馨提示: webp-server 默认生成的config.json
配置文件实例及其参数解释。1 2 3 4 5 6 7 8 9 10 $ cat /opt/webps/config.json { "HOST" : "127.0.0.1" , "PORT" : "3333" , "QUALITY" : "80" , "IMG_PATH" : "/usr/share/nginx/html" , "EXHAUST_PATH" : "/opt/webps/cache" , "ALLOWED_TYPES" : ["jpg" ,"png" ,"jpeg" ,"bmp" ], "ENABLE_AVIF" : false }
HOST:一般不修改。
PORT:webp_server_go 的运行端口。
QUALITY:转换质量,默认为 80%。
IMG_PATH:固定格式,可以为 /usr/share/nginx/html
目录路径 或者 Remote Backend 站点 "IMG_PATH": "https://test.webp.sh"
EXHAUST_PATH:固定格式,/运行 Halo 的用户名/.halo/cache
ALLOWED_TYPES:需要转换的格式
温馨提示: 默认情况下"ENABLE_AVIF": false
是禁用 AVIF 支持,因为将图像转换为 AVIF 会消耗 CPU。 温馨提示: 使用 prefetch
参数会将您的所有图像转换为 WebP, 如果要在预取时控制要使用的线程,请添加 -jobs=4, 默认情况下它将使用您所有的 CPU 内核。
1 2 3 4 5 6 7 $ lscpu | grep "^CPU(s)" CPU(s): 2 /usr/local /bin/webp-server -prefetch -jobs =1 --config=${INSTALL_HOME} /config.json
Step 2.当然也可使用systemd来管理webp服务,好在 webp 为我们提供标准的 systemd 服务文件, 可使用如下命令进行生成与配置。
1 2 3 4 /usr/local /bin/webp-server -dump-systemd > /lib/systemd/system/webp-server.service systemctl daemon-reload systemctl enable webp-server.service systemctl start webp-server.service
温馨提示: 使用 -dump-systemd
参数生成的配置文件,其中默认的 webp-server 路径为 /opt/webps/webp-server
,并且配置文件路径为 /opt/webps/config.json
,如果你的安装路径不是上述安装路径请更改/lib/systemd/system/webp-server.service
中对应路径。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ cat /lib/systemd/system/webp-server.service [Unit] Description=WebP Server Go Documentation=https://github.com/webp-sh/webp_server_go After=nginx.target [Service] Type=simple StandardError=journal WorkingDirectory=/opt/webps ExecStart=/opt/webps/webp-server --config /opt/webps/config.json Restart=always RestartSec=3s [Install] WantedBy=multi-user.target
扩展补充: 使用Supervisor托管启动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [program:webpserver] command =/your/webservergo/path/webp-server-linux-amd64 --config=/your/webservergo/path/config.jsondirectory=/your/webservergo/path autorestart=true startsecs=3 startretries=3 stdout_logfile=/your/log /path/webpserver.out.log stderr_logfile=/your/log /path/webpserver.err.log stdout_logfile_maxbytes=2MB stderr_logfile_maxbytes=2MB user=root priority=999 numprocs=1 process_name=%(program_name)s_%(process_num)02d
Step 3.Nginx 配置示例只允许图像发送到 WebP Server Go,其他扩展应该只发送原始文件,让您的 Nginx 访问图片后端代理到 proxy_pass http://localhost:3333/
,你的 webp-server 就可以运行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 server { listen 80; listen 443 ssl http2; server_name static.weiyigeek.top; charset utf-8; access_log /var/log /nginx/static/static.log custom buffer=128k flush=3m; add_header Access-Control-Allow-Origin '*.weiyigeek.top' ; add_header Access-Control-Allow-Methods 'GET,POST' ; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' ; add_header Strict-Transport-Security "max-age=15768000;includeSubDomains;preload" always; add_header X-XSS-Protection "1; mode=block" ; ssl_certificate /root/.acme.sh/weiyigeek.top_ecc/fullchain.cer; ssl_certificate_key /root/.acme.sh/weiyigeek.top_ecc/weiyigeek.top.key; ssl_session_cache shared:MozSSL:10m; ssl_session_timeout 1d; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4; ssl_prefer_server_ciphers on; location ~* \.(?:jpg|jpeg|gif|png)$ { proxy_pass http://127.0.0.1:3333; proxy_set_header X-Real-IP $remote_addr ; proxy_hide_header X-Powered-By; proxy_set_header HOST $http_host ; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0' ; } location ^~ /wp-content/uploads/ { add_header Cache-Control 'private' ; proxy_pass http://127.0.0.1:3333; } }
检查并重载Nginx配置:1 2 3 4 5 nginx -t nginx -s reload
温馨提示: 上述配置中我添加了Nginx安全方面的配置,如果你只是测试验证则可以取消上述ssl等安全配置。
Step 4.重载 nginx 后查看源站图片相应头与通过webp-server图片响应头的区别。
weiyigeek.top-webp-server images
温馨提示: WebP Server Go 将呈现以下标头etag
和x-compression-rate
作为响应, 前者格式为W/"<content length>-<CRC Checksum of the file>"
,而后者格式为 size(webp_image)/size(original_image)
如果超过1则返回原图。
Step 5.我们还可以在webp服务器中支持多路径,仅仅只需要一个创建链接符号 ,例如:ln -s /app/weiyigeek.gitee.io/img/ /usr/share/nginx/html/blog/
,然后在分别访问如下验证区别。
weiyigeek.top-webp-server banner
从上述两个对比结果中可以看到使用webp-server转换后的图片体积直线下降, 此处以banner.jpg
图片文件为例,可以看到从原图98K下降到了17.57K。1 2 3 4 5 6 7 8 9 $ ls -alh banner.jpg -rw-r--r-- 1 ubuntu ubuntu 98K Apr 13 20:40 banner.jpg $ ls /opt/webps/cache/blog -rw-r--r-- 1 root root 18K Jul 27 14:33 banner.jpg.1649853609.webp
Docker安装部署 描述: 如果要运行 webp-server insider docker 容器,可以运行以下命令。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 docker run -d -p 3333:3333 -v /path/to/pics:/opt/pics --name webp-server webpsh/webp-server-go tee docker-compose.yml <<'EOF' version: '3' services: webp: image: webpsh/webp-server-go restart: always volumes: - ./path/to/pics:/opt/pics - ./path/to/exhaust:/opt/exhaust - ./config.json:/etc/config.json ports: - 127.0.0.1:3333:3333 deploy: resources: limits: memory: 200M EOF
0x02 博客网站图片资源访问优化实践 描述: 此处我利用自己的博客网站 (https://blog.weiyigeek.top ) 进行将使用webp_server_go,将网站中的图片优化前后的访问情况进行对比。
步骤 01.首先将webp_server的config.json文件中IMG_PATH
指向我们的博客在Linux中的绝对地址目录,随后重启webp-server.service.
步骤 02.然后修改Nginx中针对博客站点的配置(/usr/local/nginx/conf.d/blog.conf
),将图片访问全都代理到本地的3333端口(127.0.0.1:3333),修改后重载nginx;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ more /usr/local /nginx/conf.d/blog.conf location ~* \.(?:jpg|jpeg|gif|png)$ { proxy_pass http://127.0.0.1:3333; proxy_set_header X-Real-IP $remote_addr ; proxy_hide_header X-Powered-By; proxy_set_header HOST $http_host ; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0' ; } nginx -t nginx -s reload
步骤 03.当Nginx重载后我们便可观察开启webp_server访问后端图片与直接访问后端图片网站访问速度的区别(在开启前我已经进行相应的测试截图)。
weiyigeek.top-优化后访问速度VS
从图中我们可以得出在未使用webp_server
进行图片转换时其传输的字节数以及完成耗时,都要大于开启webp_server
图片转换的站点。
步骤 04.为了更加直观的展示 Web 站点性能如何,我们可以使用 Google 的 PageSpeed Insights 进行分析,并按照分析结果中的优化推荐进行操作。
站点性能结果地址: https://pagespeed.web.dev/report?url=https://blog.weiyigeek.top
weiyigeek.top-PageSpeed Insights result
从上述图中可看到左边图为优化前、而右边图则优化后的结果,可知引入 WebP Server Go 可以无缝转换图片为 WebP,可以让站点图片加载速度更快,并且无需更改现有网站上图片资源路径,极大的方便各位博客以及网站站长。