布局偏移
累计布局偏移 Cumulative Layout Shift(CLS)是一项 Web 指标。
布局偏移如图所示,元素突然变化的高度影响了用户交互体验:
一般给图片一个高度就可以了,但最好是能自动化,而不是手写。
看到了这篇博文 累计布局偏移修复方案改进 —— 自动生成图片宽高,不过他是从腾讯云对象存储获取的图片宽高,而我都将图片存储在了 Hugo 配置目录的 static/img/
文件夹。
我平时在 Markdown 里都是直接写的 path:
![](/img/example.webp)
解决本地图片的偏移问题
参考 How to prevent CLS in Hugo,利用 Hugo 的 Render Hooks 功能重新渲染图片相关代码,获取图片的宽高,在 <img>
标签里加上 width
和 height
属性。
不知道为什么照他的办法,在配置中加入了 mounts
相关属性,仍然不起作用,不太会前端和 Hugo,摸索着改了改。
创建 layouts/_default/_markup/render-image.html
文件:
<p>
{{ if hasPrefix .Destination "/img" }}
{{ $img := os.ReadFile (path.Join "/static" .Destination) | resources.FromString .Destination }}
{{ if ne $img.MediaType.SubType "svg" }}
<img loading="lazy"
src="{{ .Destination | safeURL }}"
alt="{{ .Text }}"
width="{{ $img.Width }}"
height="{{ $img.Height }}"
style="max-width: 100%; height: auto;"
/>
{{ end }}
{{ if or (not $img) (eq $img.MediaType.SubType "svg") }}
<img loading="lazy" src="{{ .Destination | safeURL }}" alt="{{ .Text }}" />
{{ end }}
{{ else }}
<img loading="lazy" src="{{ .Destination | safeURL }}" alt="{{ .Text }}" />
{{ end }}
</p>
在他的基础上手动加上了 /static
地址前缀,不然这个 os.ReadFile
方法一直报错;
加上了 style="max-width: 100%; height: auto;"
,保持宽度超过父容器的图片的比例;
套了个 if else
,只处理图片地址为 /img
开头的本地图片,并可以显示网络图片,但是网络图片仍然会产生偏移。
我用的是 Hugo PaperMod 主题,主页的封面图也存在这个问题,得修改 cover.html
,看不太懂,我看上面那位博主是修改的这里,确实起作用。
修改最外层的 {{- else }}
里的内容(Hugo PaperMod 6.0 版本),和之前的一样,就是替换一下 src
和 alt
的属性值:
{{- else }}{{/* For absolute urls and external links, no img processing here */}}
{{- if $addLink }}<a href="{{ (.Params.cover.image) | absURL }}" target="_blank"
rel="noopener noreferrer">{{ end -}}
<!-- <img loading="lazy" src="{{ (.Params.cover.image) | absURL }}" alt="{{ $alt }}"> -->
<!-- 修改,将上面那行改成下面这些: -->
{{ if hasPrefix .Params.cover.image "/img" }}
{{ $img := os.ReadFile (path.Join "/static" .Params.cover.image) | resources.FromString .Params.cover.image }}
{{ if ne $img.MediaType.SubType "svg" }}
<img loading="lazy"
src="{{ .Params.cover.image | safeURL }}"
alt="{{ $alt }}"
width="{{ $img.Width }}"
height="{{ $img.Height }}"
style="max-width: 100%; height: auto;"
/>
{{ end }}
{{ if or (not $img) (eq $img.MediaType.SubType "svg") }}
<img loading="lazy" src="{{ .Params.cover.image | safeURL }}" alt="{{ $alt }}" />
{{ end }}
{{ else }}
<img loading="lazy" src="{{ .Params.cover.image | safeURL }}" alt="{{ $alt }}" />
{{ end }}
{{- end }}