今天继续完善网站的细节体验,主要围绕「加载逻辑优化」「页面可读性」「可观测性」和「布局细节」做了一轮系统性的整理。以下是本次变更的完整记录,包含动机、实现思路、关键代码与可复用的经验。

1) 统计加载逻辑安全化(不蒜子 CDN 优先,失败隐藏)

问题背景:

  • 之前为了在 CDN 不可用时仍能看到数字,引入了一个“本地自增版”的不蒜子脚本,会把 PV/UV 累加存到 localStorage。它适合本地开发验证,但线上容易产生“数字虚高”。

目标方案:

  • 线上生产:仅加载官方 CDN,失败则隐藏统计,不做本地累加,宁缺毋滥。
  • 本地开发:可继续使用本地备份脚本,支持一键重置,便于验证页面展示逻辑。

实现文件:layouts/partials/extend_head.html

核心片段与说明:

 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
<!-- 不蒜子统计:
     - 生产环境:仅加载官方CDN,失败则保持隐藏(不使用本地累加避免误导)
     - 开发环境:加载本地版本,保留重置入口(?reset_stats=true 或 window.resetBusuanzi)
-->
<style>
/* 默认隐藏所有统计容器,等待脚本成功后再显示,避免CDN异常时出现空值 */
#busuanzi_container_page_pv,
#busuanzi_container_site_pv,
#busuanzi_container_site_uv,
#busuanzi_container_today_pv,
#busuanzi_container_week_pv { display: none; }
</style>
{{ if or (hugo.IsProduction) (eq .Site.Params.env "production") }}
<script>
(function() {
    var s = document.createElement('script');
    s.src = '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js';
    s.onerror = function(){
        console.warn('Busuanzi CDN failed, stats will remain hidden.');
    };
    document.head.appendChild(s);
})();
</script>
{{ else }}
<script defer src="{{ "js/busuanzi.min.js" | relURL }}"></script>
{{ end }}

同时将页脚仅保留“本页阅读数”,避免站点 PV/UV 在开发环境被误解:

1
2
3
4
5
<div class="site-stats">
  <span id="busuanzi_container_page_pv" style="display: none;">
    <i class="fas fa-eye"></i> 本页阅读 <span id="busuanzi_value_page_pv"></span>
  </span>
</div>

经验要点:

  • 数据展示要“可信为先”。加载失败时宁可不显示,也不要展示可能误导的数据。
  • 本地与生产分支逻辑清晰,可复用到其他第三方脚本。

2) 单页可读性增强:展示 .Description 与底部标签列表

动机:

  • 文章的 description 能帮助读者“秒懂主旨”,对 SEO 也友好;底部标签有助于站内导航与系列阅读。

实现文件:layouts/_default/single.html

启用页头说明块:

1
2
3
4
5
{{- if .Description }}
<div class="post-description">
  {{ .Description }}
</div>
{{- end }}

启用底部标签列表:

1
2
3
4
5
6
7
{{- if .Params.tags }}
<ul class="post-tags">
  {{- range ($.GetTerms "tags") }}
  <li><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></li>
  {{- end }}
</ul>
{{- end }}

使用方法:在文章 Front Matter 中补充:

1
2
description: "这是一段简要说明"
tags: ["Hugo", "优化", "建站日记"]

3) 启用面包屑导航(全站路径可见)

动机:

  • 提升定位与回溯路径的能力,减少迷路感。

实现:

  • 单页启用:layouts/_default/single.html
1
{{ partial "breadcrumbs.html" . }}
  • 列表页已有:layouts/_default/list.html(已包含)
  • 归档页添加:layouts/_default/archives.html
1
{{- partial "breadcrumbs.html" . }}

样式微调:assets/css/extended/blank.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.breadcrumbs {
  margin-bottom: 20px;
  padding: 12px 16px;
  background: rgba(var(--entry-rgb), 0.8);
  border-radius: 8px;
  border: 1px solid var(--border);
}
.post-footer>.breadcrumbs {
  justify-content: flex-end;
  margin-top: 20px;
  padding: 8px 12px;
}

4) 代码行号与顶部工具条的位移问题修复

现象:

  • 启用行号后(Hugo 会把代码渲染为包含行号列的表格),原先的“复制按钮”和“Mac 顶栏”只挂在代码列容器上,未覆盖行号列,造成顶部错位。

方案:

  • 在有行号的情形下,把“复制按钮”和“顶栏”挂载到外层 .highlight 包裹容器(或表格)上,并将其设为定位上下文,保证顶栏与按钮横跨两列且不被裁切。

实现文件:layouts/partials/footer.html(挂载逻辑)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
} else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
  const tbl = codeblock.parentNode.parentNode.parentNode.parentNode.parentNode;
  let wrapper = tbl.parentNode;
  while (wrapper && !wrapper.classList?.contains('highlight')) {
    wrapper = wrapper.parentNode;
  }
  const mountTarget = wrapper || tbl;
  mountTarget.style.position = 'relative';
  mountTarget.classList?.add('code-table');
  mountTarget.appendChild(copybutton);
  mountTarget.appendChild(macTool)
} else {

配套样式:assets/css/extended/code.css

1
.copy-code { position: absolute; top: -22px; right: 8px; z-index: 2; }
1
.mac-tool { position: absolute; top: -25px; height: 25px; z-index: 1; }
1
2
3
.code-table { position: relative; width: 100%; }
.code-table td { vertical-align: top; }
.code-table .lntable { width: 100%; }

经验要点:

  • 行号模式下要以“外层容器”为定位上下文,避免工具条只覆盖代码列。
  • 需要适配主题自带的 highlighttable 样式(PaperMod 已有良好支持)。

5) 评论系统与统计策略的统一

现状:

  • 评论使用 Giscus;Gitalk 配置与入口已清理(防混用)。
  • 统计在生产严格依赖官方 CDN,失败隐藏;开发加载本地脚本并提供清零口子。

涉及文件:

  • config.yml(删除 Gitalk 配置注释块)
  • layouts/partials/comments.html(Giscus 入口)
  • layouts/partials/extend_head.html(不蒜子加载策略)

6) 其它小修小补

  • 删除历史“下雪特效”的残留注释,避免混淆:layouts/_default/baseof.html
  • 优化面包屑在暗/亮主题下的可读性,增强圆角与分隔视觉。
  • 保持文章页分享、目录、面包屑三者的布局不冲突。

本次变更带来的影响

  • 线上数据“可信度提升”:只显示来自官方脚本的统计;失败静默,不误导。
  • 阅读体验“更加规整”:有 description 的文章更容易被快速理解;标签可助力站内跳转。
  • 代码块“更稳定”:行号+工具条并存时不再出现顶端错位。
  • 导航“更清晰”:面包屑在单页/列表/归档都可用。

复用建议

  • 任何第三方脚本(统计、埋点、图床)都可以使用“生产仅CDN、失败隐藏;开发本地回退+重置”的模式,既可保障线上数据的可信,又不影响本地调试效率。

后续计划

  • 统一脚本加载时序(defer/async)与资源指纹策略。
  • description 没有的文章生成摘要兜底,提升整体 SEO 质量分。
  • 完善 404 与站内搜索的可达路径(结合面包屑与推荐文章)。

—— 以上记录,留作备忘与分享。