自动使用 WebP 图片

最开始我的图片是放到 sm.ms 图床上,但是访问起来加载得非常慢。后来发现,是因为每个图片都比较大,图片一多就显得比较慢了。
于是就把图片都换成了 WebP 格式,这样图片的大小就缩小了很多。但是由于 sm.ms 不支持 WebP 格式,于是只能把图片存在 Github 上。

直到有一天我用我的 iPad 打开自己的网页,咦,我的图片呢???

后来才知道,万恶的 Safari 依然不支持 WebP 格式!!!

20200330 更新:突然发现,在更新到 iPadOS 14 之后,Safari 实际上已经支持 WebP 了。

没有办法,只好自己添加判断代码。对于支持 WebP 格式的浏览器自动加载 WebP 图片,其余则加载原始的 jpg/png 图片。

我的 _config.yml 配置文件中是:

1
2
3
4
5
6
custom_file_path:
footer: source/_data/footer.swig
lazyload: true
pjax: true
fancybox: false
mediumzoom: true

本来是一直启用 pjax 的,但是发现网页跳转后,我添加的代码不会自动执行,于是只好暂时禁用了,待找到解决办法再启用吧。

20200328 更新:启用 pjax,在网页跳转后,表面上显示图片的链接还是指向原始的 jpg/png,但是通过开发者工具可以确认,网页加载的实际上是 WebP 图片。

20200329 更新:如果使用 fancybox 作为图片放缩工具,在点击图片放大后还是会重新加载 jpg/png 图片,而换用 mediumzoom 之后就没有这个问题了,图片的链接也正常指向 WebP 了。

但是 fancybox 在移动端的使用时有问题,放大图片会发现图片位置不在屏幕中央,而是会偏上方,有时甚至会在屏幕之外。

这个貌似不是 fancybox 的问题,貌似是因为我的页面里公式太长造成的。

博客文件夹/source/_data/footer.swig 中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
function checkWebp(callback) {
var img = new Image();
img.onload = function () { callback((img.width > 0) && (img.height > 0)); };
img.onerror = function () { callback(false); };
img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
}
function showImage(useWebp) {
var imgs = [].slice.call(document.querySelectorAll('img'));
imgs.forEach(function (e) {
if (useWebp) {
var src = e.getAttribute('data-src')
src = src.replace(/\.jpg$/, '.webp').replace(/\.png$/, '.webp');
e.setAttribute('data-src', src);
}
});
}
</script>
<script{{ pjax }} async>
checkWebp(showImage);
</script>

注意如果没有启用 lazyload 功能的话,应该把 data-src 都变成 src

然后插入图片的时候正常插入就可以了,然后使用 cwebp 把图片都转成 WebP 格式,注意放到相同的文件夹内,并使用相同的文件名(不含后缀)。cwebp 命令的使用格式:

1
cwebp result.png -o result.webp

当然也可以借助 智图 等工具进行转化。


参考资料:

  • https://akarin.dev/2019/10/22/upgrade-to-webp/
  • https://segmentfault.com/a/1190000007482148