重新设计博客主题

Leo's Field, mkII.

2019年9月,我编写了这个博客的第一套主题。这套主题伴随着我走过了一年半的时间,并成功达成了“激励写作”这一个目标。毕竟好不容易写了个博客模板,总得多写点什么吧(笑)。

不过按照我现在的审美标准来看,这套主题还是有很多的改进空间的。于是便有了这一次的重新设计。

由于新主题和旧主题一脉相承,也许可以先浏览一下之前的 诞生记录

传承

由于之前的主题还算满意,有很多用下来还不错的部分都留了下来。比如,新主题还是基于 Hugo 撰写的。我原来想切换到 Zola 上去的,毕竟 Zola 是用 文明的 Rust 写成的,而且 Zola 的模板系统的坑少得多,不过由于 Hugo 的 Org-mode 支持更加完善 Org-mode真香! ,这次还是用 Hugo。

精简的 JavaScript 也流传了下来。这一次,整个博客只有 35 行 JS 代码,除此以外的排版效果全部是由 HTML+CSS 配合实现的。

当然,右下角的 阅读进程/回到顶部 小按钮也保留了下来。我觉得这是一个很酷的设计,回到顶部按钮翻上来的动画尤其使人愉快。

快一点!更快一点!

这次重写的目标之一就是使浏览过程更加流畅迅捷。因为 Hugo 是静态页面生成器,所有页面都是预先生成然后以静态站点形式服务的,这个站点应该已经相对快了(毕竟不用等 PHP 或者 Node 现场生成页面)。所以能提升的地方有限,我们要在页面上的资源文件开刀了。

WebP 与 AVIF: 现代的图片格式

之前的主题仅支持 Org-mode 自带的图片插入格式,所以说我一般会将图片手动压缩成 JPG 格式,缩小尺寸并降低质量,然后插入到文章中。但是由于 JPG 比较旧了,在压缩比和压缩后的质量上都不是很好。Google 推出的 WebP 提供了更好的压缩比与质量,而且现在已经可以被大部分浏览器所接受。再新潮一点的话, AVIF 是一个基于最新的 AV1 视频编码的图片格式,能够提供比 WebP 都好的压缩比(而且能在低文件大小的情况下仍然提供相当不错的画质)。然而因为 AVIF 还很新,只有最近(相对于2021年4月时)版本的 Chrome 和 Firefox 提供了支持。

这次重写引入了对于 WebPAVIF 的支持。由于 Hugo 不提供对这两种格式的内建支持,这里使用了一个脚本来调用 ImageMagick 将原图片转换成 WebP 和 AVIF,然后新增了一个插入图片的 shortcode 以自动插入新格式的图片。为了兼容老浏览器,这个 shortcode 会创建一个 <figure> HTML 节点,里面标识了相同图片的不同格式版本,这样浏览器可以选择能支持的最佳图片格式。

既然已经用上 shortcode 了,我顺手在 <img> 里面加上了 惰性载入 (lazy loading) 和 异步图片解码 (async decoding) 的设置。这样,在页面加载过程中,这些图片不会被立即加载。只有在用户移动到图片附近时,图片才会被加载并被解码。这种行为可以大大加速页面的加载时间(因为不用在载入页面时对着白屏等图片加载完成了)。

唯一的问题是,由于用了 shortcode,我们不能再用原生的 Org-mode 图片语法了。不过这也不算什么太大的麻烦。

削减字体大小

此博客大量使用了在线字体。虽然这样可以让博客看上去很棒,但是这也意味着加载时得传输不少额外的数据。在老版本的主题中,在一个没什么图片的页面上,字体几乎占据了 90% 以上的数据传输量。虽然现代浏览器都可以缓存字体(下次访问就不用再下载一次了),但是这么多巨大的字体文件终究不是很理想。

字体占据了总传输量的很大一部分
字体占据了总传输量的很大一部分

不过,既然这个博客只会用到英文字符和一些符号,我们完全可以干掉那些不被使用的字符。

我们可以用 pyftsubset 去掉不需要的字形:

1
2
3
4
5
6
7
# Note that this is fish shell syntax
# Remove everything but characters speficied in glyphs.txt
for i in *.ttf; pyftsubset $i --name-IDs+=0,4,6 --text-file=glyphs.txt ; end
# And replace the original files, since pyftsubset will add .subset to the filename
for f in *; mv $f (string replace '.subset' '' $f) ; end
# Finally, compress them for browsers use
for i in *.ttf; woff2_compress $i; end

在这些操作之后,现在每一个字体只需要 15~20 KiB ,相比原来一个字体 ~150 KiB 来说,好太多了。

让 CloudFlare 缓存所有页面

这个博客一直在使用 CloudFlare 的 CDN 服务。不过 CloudFlare 在默认情况下只会缓存 CSS, JS 和图片等静态数据,而不会缓存 HTML 页面。这就导致了每次有人访问时,CloudFlare 都会访问源站,再将源站返回的页面交给用户。

不过既然这是个纯静态页面,我们完全可以让 CloudFlare 同样缓存所有的 HTML 页面。只需在域名的控制面板 - Page Rules 里面天下如下规则即可:

1
2
Match: szclsya.me/*
Then the settings are: Cache Level, Cache Everything

页面设计

这次改版最明显的改动就是从单栏布局改成双栏了。从排版角度上来说,每行宽度超过 100 个英文字符会导致阅读时跟踪行变得困难,所以在第一版时单栏的宽度便被限制在了这一范围之内。但是这也意味着在宽屏上,文字区域两侧会有很多浪费的空间。因此,这次重写试图用双栏来利用那些浪费的空间。

这也意味着我们有了更多的排版设计机会。如果你正在使用宽屏阅读的话,你也许已经注意到了浮在左侧的一些补充性文字以及图片的说明。除此以外,在 标签 页面里,左栏被用作显示标签名,而在 文章 列表中,左侧的空间被用来显示文章的发表时间。

标签页
标签页

字体选择

字体选择没有经过特别大的变化:Vollkorn 用作衬线体,IBM Plex Sans 用作无衬线体,Iosevka 用作等宽字体。这次新增了一个衬线体:Lora。它将替代 Vollkorn 成为这套主题的主要英文衬线字体,而 Vollkorn 将会被用在一些特殊的排版场合上。

在具体的字体使用上,UI 和正文字体选用无衬线体,而标题主要是衬线体。从阅读角度上来说,衬线体更适合作为主要的阅读字体(而且看上去也更有意思)。但是考虑到大部分屏幕的分辨率并不足以漂亮地显示衬线体(以及在暗色模式下有可读性问题),这里还是做了妥协,使用非衬线字体作为主要的阅读字体。

值得一提的是就像之前的版本一样,我还是没有用任何的中文 webfont。Google Fonts 和 Abobe TypeKit 都有中文 webfont 方案,但是在我看来都和优雅相去甚远。因此,这里还是得委屈一下 Windows 用户了(逃)。

暗色模式

暗色模式也保留了下来。这次的一个变化是在暗色模式下,背景颜色不再是纯黑,而是一个很深的灰色。这应该有助于提高可读性。

就像上次一样,暗色模式是由系统的色调配置所触发的。这样做的好处是这个站点的色彩方案应该和你系统的其他部分是一致的。

尾声

这次的更改基本上就是这些了!这次更新与其说是推倒重来,更像是对之前的理念的一种重新诠释──给作者提供强大的表现能力,并给读者愉快的阅读体验。因此,在变动之余,你应该也能在新版本的站点上找到许多熟悉的元素。

如果你想看看具体的实现细节,所有构建这个站点需要的资源以及文章的源代码全部开源于 GitHub,好奇的话可以去翻一翻。

Happy Hacking!

发表于 2021-04-12
JS
Arrow Up