博客重构记录
重构博客网站,也就是该网站的记录。
多用 CSS
近期订阅了一些英语的周刊,主要是前端相关,里面收集了很多外网博客平台上的优秀文章。其中不乏有一篇文章吸引到了我:很多时候你根本不需要使用 JavaScript。
吸引我的理由很简单。我的前端技术栈主要是 React.JS。相较于传统的「网页三剑客」,React.JS 这类现代前端框架需要客户端下载并执行更多的 JavaScript 代码。其核心的虚拟 DOM 技术虽然在过去带来了性能优势,但在现代浏览器性能已大幅提升的今天,其初始化和运行时成本有时反而不如原生方法来得直接高效。
但是,对过去的我而言,功能就是要用 JavaScript 才能做到。纯 HTML 和 CSS 能做到什么?它们又不是脚本语言。 不过在那个文章里,这个想法是片面的。现代的 CSS 技术进化很快、有着性能优异的各类方法,完全可以代替 JavaScript 来实现一些功能。
举个例子,我们想要实现主题切换功能。
如果是网页三剑客的话,我们可能会想到用 JavaScript 监听切换按钮,该按钮被点击了我们就改变被监听的类或者元素的样式。
在 React.JS 上的话,那就是存一个主题状态:如果是 light 模式就怎么怎么样;如果是 dark 模式就怎么怎么样。如果用的还是 Material-UI 或者其他 UI 框架,那大概率还会有个 theme 配置文件。
这些方案对我们而言应该都很熟悉:对啊,怎么了,这样做不是很正常吗。
其实可以更简单一些,用 CSS 的
color-mix()方法就可以办到::root { // 核心品牌色 --color-primary: #5454f8; --color-secondary: #267B54; --color-accent: #4088b8; // 使用 color-mix() 生成交互状态 --color-primary-hover: color-mix(in srgb, var(--color-primary) 85%, black); --color-secondary-hover: color-mix(in srgb, var(--color-secondary) 85%, black); --surface-interactive-hover: color-mix(in srgb, var(--surface-interactive) 80%, var(--color-primary));}// 深色主题[data-theme="dark"] { --color-primary: #818cf8; --color-secondary: #34d399; --color-accent: #60a5fa; // 深色模式下的交互状态 --color-primary-hover: color-mix(in srgb, var(--color-primary) 80%, white); --color-secondary-hover: color-mix(in srgb, var(--color-secondary) 80%, white); --surface-interactive-hover: color-mix(in srgb, var(--surface-interactive) 70%, var(--color-primary));}又或者,我们想要创建模态框。通常我们会写一个
<div>,然后写 JavaScript 来控制它的显示和隐藏、背景遮罩、锁定用户的键盘焦点、处理Esc键退出等等等等。实际上,可以直接用<dialog>来写、用::backdrop伪元素给背景遮罩添加样式和动画、用@starting-style来实现更流畅的入场动画。其他交互效果,例如按钮的颜色变化就更不用说了。这里还有一个很有意思的考量:JavaScript 很可能带来安全问题,而 CSS 是完全安全的。
带着这些全新的知识点,我重构了我的博客网站。其实之前我对于网站设计是没有一丝考量的,也不在乎 CSS 这些让我觉得「不如 React.JS 优雅高级」的技术,因此我的博客网站性能一般,对比原本主题的设计还添加了许多非必需的东西。我的顶部菜单栏出现过明显的元素堆积过多的情况,一些按钮很丑很奇怪、像是四不像、哪儿哪儿都不挨上,所以我决定先在博客网站上将部分功能撤下。其中就有搜索功能:首先它的样式我一直没有设计、难看得很;其次是这个功能我认为没必要留、不够精简。未来如果需要的话,我会想一个更好的方案。
不过在 Hexo Theme Ares 里,搜索功能还会保留,并且进行了一次小重构。
我还撤走了评论区的 Disqus 评论区,因为这东西多多少少会给我带来一些影响:今天有没有人发评论?今天有没有人作反应? 其实很没必要,本身看的人就不多。
字体
正确导入字体
我不只是将一些功能用 CSS 重构了,我还改了一下字体的导入方式,参考的是另一篇 优质的文章,具体讲了现代网站是如何错误地导入字体的。
我的博客主题原先会导入足足四个字体:
- 英语的 Open Sans
- 简体中文的 Noto Sans(其实就是思源黑体,不过我在考虑换成其他的;我个人阅读时喜欢用霞鹜文楷,但还没尝试换过,有可能和我的主题不搭配)
- 用于特殊标题的 Dosis
- 代码块用的 JetBrains Mono
这些字体都是用 Google Fonts 的 CDN 导入的。其实这种方式并非最佳实践,很容易导致性能问题:浏览器会发起两次请求,第一次用于请求 fonts.googleapis.com 这个地址、获取一个 CSS 文件,第二次则是请求 CSS 文件内的真实字体文件地址。这个过程至少会有两次网络往返,第一次请求的 CSS 文件会阻塞渲染,这意味着在它下载完成之前,页面可能是一片空白或者没有应用任何样式。为了解决这些问题,我是这么做的:
// 1. 加载真正的 Open Sans 字体@font-face { font-family: 'Open Sans'; src: url('...') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,...剩余内容已隐藏