yokila
yokila
Published on 2024-03-31 / 64 Visits
0
0

Halo 支持 WebP 图片输出

一、前言

本文旨在介绍如何通过 WebP图片格式 提高 Halo博客 的网页加载速度,以提高访客浏览页面的体验。

二、WebP是什么

WebP 是一种现代图片格式,可为网络上的图片提供出色的无损和有损压缩。使用 WebP,网站站长和 Web 开发者可以创建更小、更丰富的图片,从而提高网页加载速度。

——谷歌开发者文档

关于浏览器的支持情况,可参阅官网文档:哪些网络浏览器本身支持 WebP?

注:WebP 是开源的,最新源码(需要科学上网)

注:WebP 与 VP8 的比特流兼容,宽度和高度均为 14 位。 WebP 图片的最大像素尺寸为 16383 x 16383。

三、为什么要使用 WebP

云服务器的带宽价格实在是太贵了,个人建站购买云服务器通常只有3M、4M之类的带宽。

按照本站的实际体验来看,3M的带宽,遇到多图页面(甚至有时仅仅是六篇文章的列表页头图)加载起图片就明显吃力,往往需要好一会儿才能加载完毕,对于访客而言体验真的很差。(更别说那种几十张大体积PNG图的页面)

(如果你的带宽够大,那么考虑过并发场景呢?)

所以,急需一种能够提高图片加载速度的方式。

花钱提升带宽、进行CDN加速在不影响图片观感效果情况下降低图片体积 的选项中,我们自然是倾向于后者。

于是,本文选用 WebP 图片格式,使得博客页面上展示的图片体积可以有较大幅度的缩小,从而带来了加载性能的提升。(毕竟需要加载的数据量小了,加载速度自然就快了)

Halo官网本身其实也应用了WebP来输出图片(不信你可以去研究看看),Halo官网也有相关的优化指引文章:优雅的让 Halo 支持 webp 图片输出

另外,还有一点操作起来有些麻烦的建议(当然,你可以选择不做):上传图片前,先无损压缩一下。(即,从源头降低图片体积)

注:其实降低图片体积,还有一个好处就是降低服务器流量消耗(特别是那些每月有免费流量上限的云服务器)

四、如何使用 WebP(方式一)

将网站上的图片全部变成 WebP 图片格式,每次上传图片前都先去将图片转换为 WebP格式。

注:使用这种方式的话,很难处理存量图片的引用。因为如果你把图片变成WebP了,博文里的引用链接也要跟着改。

评价:不太现实,也麻烦,所以建议使用 五、如何使用 WebP (方式二)

4.1 转成 WebP 途径一:在线网站

网上有一些网站支持在线转换,可以直接使用,请自行去找。

4.2 转成 WebP 途径二:官方工具

首先,依据平台,下载 WebP 软件包:下载并安装 WebP

将预编译好的程序包解压到某个文件夹内。

参考谷歌提供的操作指南进行操作。

以下为有损压缩的简单示例:

前置准备:

  • Windows11环境下已下载并解压 WebP 软件包。

  • 已准备了一个等待被转换的图片,这里为 Test.jpg 图片。

执行命令:cwebp.exe -q 80 Test.jpg -o Test.webp

其中:

  • cwebp.exe:为 WebP 解压文件夹内bin目录下的对应文件,执行命令时需要指向这个文件。

  • -q:指定 0 和 100 之间的 RGB 通道压缩因数。默认值为 75。如果是有损压缩(默认),微小系数生成的文件体积较小,质量较低。使用 100 值可以实现最佳质量。对于无损压缩(由 -lossless 选项指定),较小的系数可以加快压缩速度,但生成的文件会更大。使用 100 值可以实现最大压缩。

  • Test.jpg:等待被转换的图片。

  • Test.webp:转换后的 WebP图片文件路径(文件名)。

结果展示(图片大小明显下降):

结果展示(图片显示效果差距不明显):

五、如何使用 WebP (方式二)

此方式不需要改变原有的上传图片、引用图片逻辑,存量图片数据无需变更,未来的图片操作上也不需要变化,相当于是隐性地做了优化。另外,这种方式相对独立,可插拔。

本文基于的是 webp-sh 组织开源的 webp_server_go

注:这里是在 部署halo的服务器 上操作。

注:webp_server_go 实测用一段时间后,大概会占用四五百兆的内存,所以需要服务器内存有足够的空间。

注:Halo V2.19.0 版本开始,因为 halo 会自行生成缩略图,所以大大降低了图片资源的加载速度。如果实测下来体验不是很糟糕的话,建议不必额外使用webp_server_go。

5.1 WebP Server Go

介绍(内容源自:0.11.0发布文档 + 简介页):

  • 大概原理:当我们请求一张图片时,使用 Web 代理工具转发到 webp_server_go 服务上进行处理,处理完成之后返回 WebP 格式的图片,并且会缓存处理后的图片以供后面的访问。

  • 开源源码(开源协议:GPLv3 许可):GitHub上

  • 目标:旨在不改变原始 URL 的情况下通过通过动态(On the fly)优化/压缩原始图片到更加现代的格式,解决网站输出较大体积的老格式图片(如 JPGPNG)导致服务器额外带宽开销和加载速度缓慢的问题,从而提高网页响应速度并提升页面的 Pagespeed 评分。

  • 使用 WebP Server Go 可以保持原始图片地址不变,将图片体积缩小并以更现代的图片格式(例如 webpavif)输出。

  • 无需更改图片地址,URL 中的图像地址仍可以jpgpng 等结尾,但输出为webpavif 格式。

  • 由于 webpavif 等格式有浏览器限制(例如 Firefox 77~92 版本不支持 avif 格式),所以 WebP Server Go 会根据浏览器信息自动输出一个浏览器能接受的且体积最小的图片。

5.2 Linux + Nginx 实操

本文基于:

  • Ubuntu 22.04

  • WebP Server Go V0.11.0

  • Halo V2.13

参考:

注:写这篇文章时,官网上还挂有“服务存在内存泄漏的问题”的提示,我去看了相关的 issue,似乎在 0.6.0 和 0.9.? 做了相关的优化,不确定是否已经完全解决。(所以,建议使用新版本,不要使用旧版本的 WebP Server Go )

注:官方目前推荐是用 docker 来使用 WebP Server Go,但是我这里没有使用 docker。如果你准备基于 docker 来使用WebP Server Go,则可以参考官方文档:Usage with Docker(Recommended)

注:目前 WebP Server Go 的更新还蛮频繁的,不确定等你看到这篇文章时,已经变化到何等程度,还是得多看官网文档啊!

5.2.0 确定用户

为避免权限问题,下文简单起见使用 执行halo服务的同一个用户 来执行以下操作(否则你需要给执行 WebP Server Go 的用户赋予读取 halo 图片附件目录的权限)。

5.2.1 新建文件夹

现在,先创建等下要用来放 WebP Server Go 一系列文件的目录。(具体这个文件夹放哪里,取决于你)

例如创建 webp 文件夹,执行命令:mkdir webp

进入新建的目录,执行命令:cd webp

5.2.2 下载相关依赖

详情参考: Usage with Binary(Advanced)

执行命令(需要用Root用户):apt install libvips-dev

5.2.3 下载编译好的服务文件

(如果有能力,也可以选择自己编译)

先去看一下 WebP Server Go 的发行版本:Releases

选择你想要使用的版本,复制下载链接。

在刚刚创建的新文件夹内,利用下载链接下载编译好的文件:

执行命令: wget https://github.com/webp-sh/webp_server_go/releases/download/0.11.0/webp-server-linux-amd64 -O webp-server

其中:

  • -O webp-server:(注意,是大写的 O )表示将下载下来的数据,存储到指定名字的文件中(本例中文件名为 web-server)。

现在下载下来的这个 webp-server,还不能执行,需要先配置执行权限。

给拥有者配置文件执行权限,执行命令:chmod u+x webp-server

5.2.4 配置文件

现在,开始编写 webp-server 执行需要的配置文件。

执行命令:vi config.json

{
  "HOST": "127.0.0.1",
  "PORT": "3333",
  "QUALITY": "80",
  "IMG_PATH": "/path/to/attachments",
  "EXHAUST_PATH": "./exhaust",
  "IMG_MAP": {},
  "ALLOWED_TYPES": ["jpg", "png", "jpeg", "bmp", "gif", "svg", "heic", "nef", "webp"],
  "CONVERT_TYPES": ["webp"],
  "STRIP_METADATA": true,
  "ENABLE_EXTRA_PARAMS": false,
  "READ_BUFFER_SIZE": 4096,
  "CONCURRENCY": 512,
  "DISABLE_KEEPALIVE": false,
  "CACHE_TTL": 259200
}

各个参数可参考官方文档:完整配置

其中重点:

  • QUALITY:图片质量,值范围为 0-100,100表示无损压缩。默认值:80。

  • IMG_PATH:原始图片目录。如果你使用的是 Nginx代理,则这里应该是 location 匹配路径前的那一部分路径。例如你是按照本文配置流程,则应该是到attachement 这个目录的路径。

  • EXHAUST_PATHWebP Server Go 缓存处理过的 WebP 图片存放目录。可自定义一个位置,不需要提前创建文件夹。

  • IMG_MAP:如果你的原始图片目录不止一个,则可以参考官网文档配置这个配置项。

  • CONCURRENCY:最大并发连接数,需要依据你的实际情况来。默认值:262144,我这里是降低到512。

5.2.5 启动服务

可以参考Halo的官方文章:优雅的让 Halo 支持 webp 图片输出systemd 管理服务。

WebP Server Go 支持一些命令(包括生成 systemd 的 service 文件、预处理转换原图片目录文件为 WebP 等),可参考文章:[Go 开源推荐] webp_server_go —— 可自动将 jpg, jpeg, PNG 图片进行压缩的 WebP 服务

我希望是自己手动管理,所以自行写脚本启动,下面是操作步骤。

先新建一个文件夹,用于存储执行日志。

执行命令:mkdir logs

开写启动脚本。

执行命令:vi webpServerStart.sh

#!/bin/bash
nohup ./webp-server --config=/path/to/webp/config.json >> /path/to/webp/logs/"`date +%Y%m%d`.log" &

设置脚本为可执行。

执行命令:chmod u+x webpServerStart.sh

执行脚本:./webpServerStart.sh

注:自己写脚本启动的话,如果要停止服务运行,就得通过杀进程的方式。

5.2.6 Nginx 配置转发

Nginx的安装和使用说明,可参考:Linux nginx的安装与入门

此时看你之前 Nginx 是用什么用户管理的,就用哪个用户操作。

编辑代理 halo服务的 nginx配置文件。

例如执行命令:vi yokila.conf

在 代理halo服务的server 中添加以下内容:

location ^~ /upload/ {
        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配置了。

执行命令:nginx -t

执行命令:nginx -s reload

六、实际体验

在浏览器里,摁 F12 开启开发者模式,刷新你的博客页面。

注:如果出错的话,WebP Server Go 会自动输出原图片,相当于没做优化,仅看页面上看不出来是是否正常进行了压缩。

查看网络请求的信息,看到图片是 WebP 类型,说明很成功!

另外,可以观测一下 配置里的这个 EXHAUST_PATH 文件夹,看看有无正常生成 webp 文件缓存

还有观测一下 日志文件,看看是否有报错。

注:如果发现有一些图没压缩,则可以依据日志进行问题排查。


Comment