惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Last Week in AI
Last Week in AI
I
InfoQ
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Help Net Security
D
Docker
www.infosecurity-magazine.com
www.infosecurity-magazine.com
B
Blog RSS Feed
Forbes - Security
Forbes - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Latest news
Latest news
S
SegmentFault 最新的问题
J
Java Code Geeks
C
CXSECURITY Database RSS Feed - CXSecurity.com
MongoDB | Blog
MongoDB | Blog
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
F
Full Disclosure
Engineering at Meta
Engineering at Meta
AWS News Blog
AWS News Blog
月光博客
月光博客
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
雷峰网
雷峰网
博客园_首页
Project Zero
Project Zero
美团技术团队
Google DeepMind News
Google DeepMind News
IT之家
IT之家
P
Palo Alto Networks Blog
有赞技术团队
有赞技术团队
S
Security @ Cisco Blogs
U
Unit 42
C
Cisco Blogs
Hugging Face - Blog
Hugging Face - Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
S
Schneier on Security
TaoSecurity Blog
TaoSecurity Blog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
Help Net Security
Help Net Security

流动

对口型视频合成方案对比:Wav2Lip、VideoReTalking 与 MuseTalk 2026 音色克隆方案对比:IndexTTS-2、CosyVoice、GPT-SoVITS、Fish Speech、VoxCPM 部署与实测 AI Agent折腾记(OpenClaw / Hermes Agent) 我的2025年 大连之行 回家收麦 六一儿童节爬长城 Golang database/sql 数据库断线自动重连机制解析 Golang默认Http Client导致的cannot assign requested address错误 清明踏春,爬山看海 购入小牛G400T电动车 北京的三月飞雪 wrenAI本地LLM模型部署 天津一日游 2024年终总结 停止使用staticfile.org服务 使用 ImageMagick 自动添加水印,保护图片版权 如何注册一个.sol域名 奥森公园半日游 昌平42公里骑行绿道打卡 十月一日爬慕田峪长城 博客被恶意镜像 Github Pages 部署流程解析 搭建个人锻炼页面 你好 Follow 中秋爬山 Google Adsense的审核之旅 让你的IPFS站点持久在线:接入Filebase的Names(IPNS)服务 一次简短的青岛之行 解决 "undeclared name: any (requires version go1.18 or later)" 编译错误 搭建自托管IPFS Gateway服务,替代Cloudflare的IPFS Gateway 302跳转的跨域问题(CORS) GORM增加sqlcommenter特性 源码分析:GORM是如何生成sql的 工银亚洲网银密码重置 加速Cloudflare访问 2023年终总结 2023年12月北京暴雪记录 使用Hugo实现响应式和优化的图片 加速Google Analytics 使用Google Indexing API加速博客收录 在Netlify上部署Twikoo评论系统 利用Github Actions定时抓取微博 北大口腔牙周刮治记录 故乡回忆之旅 解决Golang使用go get安装包后找不到可执行文件的问题 修正Hugo的JSON Feed格式 我的学车之路 将博客部署到星际文件系统(IPFS) 新冠疫情后的第一个春节 第一次清理键盘 2022年终总结 去掉Cloudflare烦人的email-decode.min.js请求 累计布局偏移修复方案改进 —— 自动生成图片宽高 优化博客的累计布局偏移(CLS)问题 将博客部署到Cloudflare Pages 奥林匹克公园向日葵之旅 记第二次洗牙 记录2022年海淀幼升小 Golang解析json的一个问题 疫情下的生活 整理下博客的一些调整 疫情下的五一假期 自己动手,更换thinkpad x1硬盘 二刷百望山 带娃游颐和园 博客架构说明 难得的清明假期 十一年的等待,终于拿到了liudon.com域名 被隔离的一周 mysql中字符串和整型自动转换的问题 一次惊心动魄的Mysql更新操作 如何在北京公积金网站上修改婚姻状况 PHP7.2编译安装后没有php.ini文件的问题 检测网站支持的SSL/TLS协议版本 记一次难忘的手术经历 十一假期经历 Swoft 框架运行分析(五) —— ConsoleProcessor模块分析 Swoft 框架运行分析(四) —— EventProcessor模块分析 一个git submodule update引发的问题 一个Curl的耗时长的问题 Swoft 框架运行分析(三) —— BeanProcessor模块分析 Swoft 框架运行分析(二) —— AnnotationProcessor模块分析 Swoft 框架运行分析(一) BCMath 与 科学计数 Flink Could Not Resolve Resourcemanager Address 解决Sublime Text安装包时"There Are No Packages Available for Installation"的报错 关于本站 2019,新开始
当Hugo遇上AVIF,优化图片加载
Liudon · 2024-09-30 · via 流动

avif-on-hugo

这篇文章会介绍基于Github Workflow使用ImageMagick生成AVIF图片,来优化Hugo站点的加载速度。

背景

AVIF是什么?

AVIF(AV1 Image File Format)是一种基于AV1视频编码标准的图像文件格式。

A modern image format based on the AV1 video format.

AVIF generally has better compression than WebP, JPEG, PNG and GIF and is designed to supersede them.

browser support avif

在2024年,绝大部分浏览器都已经支持了AVIF格式。

ImageMagick是什么?

ImageMagick® is a free, open-source software suite, used for editing and manipulating digital images.

It can be used to create, edit, compose, or convert bitmap images, and supports a wide range of file formats, including JPEG, PNG, GIF, TIFF, and Ultra HDR.

ImageMagick是一款用于图像处理的一个工具。

对比

AVIF说的这么好,我们来验证对比一下。

对于一张PNG的图片,使用ImageMagick分别生成WEBP和AVIF格式的图片,文件大小如下:

-rw-r--r--@  1 liudon  staff   1.1M  9 29 23:02 20240922-170856.png
-rw-r--r--@  1 liudon  staff    15K  9 29 23:08 20240922-170856.png.avif
-rw-r--r--@  1 liudon  staff    25K  9 29 23:07 20240922-170856.png.webp

WEBP比PNG要节省90%左右,AVIF要比WEBP再小40%左右。

效果出奇的好,开搞吧。

使用

1. 生成AVIF文件

博客使用了Github Workflow来进行部署,所以生成ImageMagick的工作也就放在了Github Workflow上。

- name: Compress Image
run: |
    sudo apt-get update
    sudo apt-get install -y imagemagick libheif-dev
    find ./content/posts/ -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \) -exec convert {} -resize 1080x\> -quality 75 -define webp:image-hint=photo {}_1080x.webp \;
    find ./content/posts/ -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \) -exec convert {} -resize 1080x\> {}_1080x.avif \;

新增压缩图片步骤,同时生成WEBP和AVIF格式文件。

含义说明,可以自行调整:

-resize 1080x> 表示缩放到1080宽,>表示只有在原图宽大于1080时才进行缩放,小于不做处理。
-quality 75 表示处理后图片质量,值越小图越小,图片也越不清晰。
-define webp:image-hint=photo 这里是为了对齐Hugo自身的图片处理参数。

2. 使用AVIF文件

修改layouts/_default/_markup/render-image.html文件:

{{- $respSizes := slice 1080 -}}
{{- $dataSizes := "(min-width: 768px) 1080px, 100vw" -}}

{{- $holder := "GIP" -}}
{{- $hint := "photo" -}}
{{- $filter := "box" -}}

{{- $Destination := .Destination -}}
{{- $Page := .Page -}}
{{- $Text := .Text -}}
{{- $Title := .Title -}}

{{- $responsiveImages := (.Page.Params.responsiveImages | default site.Params.responsiveImages) | default true }}

{{ with $src := .Page.Resources.GetMatch .Destination }}
	{{- if $responsiveImages -}}
		{{- $imageTypes := slice -}}
		{{- if and hugo.IsExtended (ne $src.MediaType.Type "image/webp") -}}
			{{- $imageTypes = $imageTypes | append "avif" -}} <!-- avif need the first -->
			{{- $imageTypes = $imageTypes | append "webp" -}}
		{{- end -}}
		{{- if gt (index $respSizes 0) $src.Width -}}
			{{- $respSizes = slice $src.Width -}}
		{{- end -}}
		<picture>
			{{- range $imageType := $imageTypes -}}
			<source type="image/{{ $imageType }}" srcset="
			{{- $compressedImage := printf "%s_1080x.%s" $Destination $imageType -}}
			{{- $cmSrc := $Page.Resources.GetMatch $compressedImage -}}
			{{- if $cmSrc -}}
                <!--avif/webp file exist-->
				{{ $cmSrc.RelPermalink | absURL}} 1080w
			{{- else -}}
				<!-- hugo not support avif format -->
				{{ if ne $imageType "avif" }}
					{{- with $respSizes -}}
						{{- range $i, $e := . -}}
							{{- if ge $src.Width . -}}
								{{- if $i }}, {{ end -}}{{- ($src.Resize (print . "x " $imageType " " $filter) ).RelPermalink | absURL}} {{ . }}w
							{{- end -}}
						{{- end -}}
					{{- end -}}
				{{ end }}
			{{- end -}}" sizes="{{ $dataSizes }}" />
			{{- end -}}
			<img src="{{ $Destination | safeURL }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $Text }}" title="{{ $Title }}" loading="lazy" />
		</picture>
	{{- else }}
		<img src="{{ $Destination | safeURL }}" width="{{ $src.Width }}" height="{{ $src.Height }}" alt="{{ $Text }}" title="{{ $Title }}" loading="lazy" />
	{{- end }}
{{ end }}

这里如果AVIF/WEBP文件已经存在,那么直接使用对应文件(注意:我这里都是生成的1080宽,如果你有调整记得一起调整);

否则会使用Hugo自身的Image Processing生成对应格式文件。

效果

优化前:

optimize before

优化后:

optimize after

从WEBP切换到AVIF,文件大小减少了30%左右。

哈哈,太棒了,效果杠杠滴。

唯一的缺点就是每次都是全量生成图片,Workflow执行略久些(我的要5分钟左右),这里后面再优化。

从23年11月开始有的想法,在24年9月最后一天终于实现了。🎉🎉🎉