老博客的现代化手术:和 AI 结对快速翻新十年 WordPress 博客

2026年4月18日 9点热度 0人点赞 0条评论

面对 2015 年的老博客,是推翻重写还是爆改布局?借助最新 AI 模型结对,笔者仅用几个小时,完成了从前端排版到后端性能的全面现代化翻新。记一次时间性价比极佳的工程实践。

2026 年了。主站博客 (steinslab.io)伴随着笔者一路成长过来。11 年过去,当年的前卫审美放到今天最近的前端技术栈上,亟待翻修。

笔者原本觉得翻新老站是个无底洞,不如直接迁移到 Astro 等现代框架。但出乎意料的是,借助最新的旗舰 AI 模型结对,这台"现代化手术"仅花了我几个小时。这样,我就可以留更多时间给创作本身了!

全部工作只在 WordPress 后台的"附加 CSS"里完成,一行 PHP 模板都没动,也没加外部字体和 JS。 顺手还把后端 MySQL 和 PHP-FPM 的参数重新极限调优了一遍。

整个过程极其丝滑,主站可阅读性和性能极大提升,性价比极佳。这篇文章,就来盘点一下这次从前端到后端的翻新记录。

至于为什么不直接使用 Hugo 或者 Astro 现代化技术?笔者认为和旗舰模型结对重新开发迁移是非常可行的。但在 AI Coding 时代,保持一个良好的审美看来仍然是一件宝贵的技能。本身的排版、可读性,可能和后端是 wordpress 还是 astro 无关。

另外,如果读者也有基于传统 LNMP 搭建的 wordpress 博客,并且已经有比较多的内容,笔者强烈建议使用和旗舰大模型结对工作的方式进行翻新,整个过程会非常顺利且令人愉悦。


1 先体检:老主题到底哪里不对劲

笔者先把"哪里不对劲"拆成具体的条目。罗列得越细,后面修起来越不容易漏:

区域 问题
正文行宽 桌面端超过 900px,中文一行 60+ 字,眼球回扫距离过大
行高 约 1.5–1.6,反引号 inline code 会挤压上下文字
段间距 和行距差异不大,长文读到中段开始"糊"
字号 正文约 15–16px,长文偏小
字体 未显式指定中文字体,Win 上退到雅黑,Mac 上是苹方,Linux 看缘分
反引号 code 无底色无等宽,io_uring checkpoint 这种关键词和正文混在一起
标题 H2/H3 只靠字号区分,没有颜色、装饰线、序号
首页卡片 日期 / 点赞数 / 热度 / 评论 / 作者 五项平铺,权重完全相等
侧栏 按月归档堆到 70+ 项,标签云字号乱飞
页脚 单行,底下还裸露着 wpDiscuz Insert 这类插件 DOM

逐条对着看,读者大概能理解为什么笔者会产生"换衣服"的冲动。

这里面有的是字体问题,有的是布局问题,有的是信息权重问题,甚至有的是"插件漏到前端"这种尴尬的工程问题。接下来一块块处理。

当然,仅凭博主的美感是做不到这种洞察的。这些修改都是由 Claude Opus 4.6 提出的。看来在 AI Coding 时代,保持一个良好的审美看来仍然是一件宝贵的技能。


2 字体栈:先把最基础的统一起来

字体是一切排版的地基。笔者先从这里开始——它的收益最大,风险也最小。

2.1 为什么不选 Google Fonts

答案朴素:Google Fonts 的域名在国内访问不到

fonts.googleapis.comfonts.gstatic.com 被墙多年。国内用户访问会经历:DNS 能解析 → TCP 连接超时 → 浏览器等大约 30 秒才 fallback。这 30 秒里,页面上所有字体相关的文字要么不可见(FOIT),要么一闪一闪。

老博客本身内容质量不差,不需要靠这种方式给读者添堵。

自托管也考虑过。中文字体全字库动辄 20MB 起步,想要观感好就得做 subset——按 Unicode Range 切片、用 fonttools 精简字符集、转 woff2、挂 font-display: swap。这一整套下来就是个小工程了。不做网络文字上投入,改为系统字体回退方案。

2.2 纯系统字体回退的设计思路

核心理念是:不加载任何外部字体,全靠浏览器逐字符匹配的能力,在不同操作系统上分别命中各自最好的字体。

中英文要分栈,这是 CSS 层面一个经常被忽略的事实:浏览器在遇到具体字符时,会font-family 列表依次寻找能渲染该字符的字体。英文优先匹配 Inter / SF Pro / Segoe UI,中文自动落到苹方 / 思源 / 雅黑。

最终用的字体栈大致这样:

--font-cn: "PingFang SC", "HarmonyOS Sans SC",
           "Source Han Sans SC", "Noto Sans CJK SC",
           "WenQuanYi Micro Hei", "Microsoft YaHei", sans-serif;

--font-en: "Inter", -apple-system, BlinkMacSystemFont,
           "Segoe UI", Roboto,
           "Helvetica Neue", Helvetica, Arial, sans-serif;

--font-mono: "SF Mono", "Cascadia Code", "Cascadia Mono",
             "JetBrains Mono", "Fira Code",
             Menlo, Consolas,
             "Liberation Mono", "DejaVu Sans Mono", monospace;

它在各平台会命中的方式列出如下:

平台 中文命中 英文命中 等宽命中
macOS / iOS 苹方 PingFang SC SF Pro SF Mono
Windows 10/11 微软雅黑 Segoe UI Cascadia / Consolas
Android 思源 Noto CJK Roboto Roboto Mono
Ubuntu / Fedora 中文环境 思源 Noto CJK 系统默认 DejaVu Mono
Arch 纯英文装机 文泉驿微米黑 兜底 DejaVu Sans DejaVu Mono

Mac 用户看到的观感和系统 UI 一致;Windows 用户会差一档(雅黑在小字号下有轻微锯齿,但已经是 Win 上最好的选择);Linux 的情况取决于用户自己的配置——笔者专门把 WenQuanYi Micro Hei 加到中文栈末尾,给那些没装思源的老 Linux 用户留个兜底。纯英文 Linux 看到 sans-serif 兜底、可能还是豆腐块,但这类用户占比极低,且懂得自救。

全站零网络请求。 这是笔者最终选择"纯系统回退"的唯一理由。

2.3 修改对比

修改前

修改后


3 品牌与顶栏:辉光管 logo 和导航一体化

定完字体栈以后,笔者盯了一眼顶栏——还是那一行光秃秃的"团子云技术 – Steins;Lab"纯文字。后面正文区、卡片、侧栏、页脚都要动,但顶栏先成了视觉短板:和内容区摆在一起,它像是从旧模板直接撕下来贴上去的。品牌没有识别点、中英文平级、hover 只是底线变白——连"当前在哪一页"都看不出来。

从概念、SVG 到 nav 配色是一整条链路,和 Opus 4.6 结对设计的过程也很有意思。

3.1 方向:从"赛博朋克终端"到"辉光管实验室"

第一版的想法是命令行终端——深色底、霓虹绿、> prompt、闪烁光标。符合"技术博客"的刻板印象。

当时用 SVG 拉了一版示意,矢量稿放在同目录 blog-wordpress-refresh-terminal.svg。正文用 <img> 嵌入,Markdown 预览和站点都省事;img / background-image 下片内动画多半静止,直接打开 svg 文件或在页面里内嵌才能看到完整动效——和后文辉光管定稿遇到的情况一样。

第一版:赛博终端风格示意(霓虹绿 prompt、渐变「云」字)

画完以后自己看了一眼就否了:太通用。绿色终端这个审美从 GitHub README 截图到各种 devtools 主题,2018 年以后已经遍地都是。"团子云技术"这个博客名本身带着"研究所"的味道(Steins;Lab 致敬《命运石之门》里的"未来小工具研究所"),应该是更具体、更硬件的东西。

换了第二个方向——辉光管(Nixie Tube)

辉光管是 1950–70 年代用来显示数字的气体放电管,玻璃管身里封着冷阴极造型的数字字符,通电以后整个字符会发出暖橙色的光。大学物理实验室、老式仪表、示波器面板上经常能见到。

第二版示意如下,矢量稿为 blog-wordpress-refresh-nixie.svg。同样用 <img> 嵌入;nixie-flicker 与光标动画在 img 里多半静止,直接打开 svg 可看到动效。

第二版:辉光管 + 单行中英文示意

这个方向一下子对上了:

  • 复古而具体:和 2026 年满街跑的"绿屏终端"拉开距离
  • 硬件质感:和"技术博客"的定位吻合,比通用 IDE 配色更有个性
  • 暖色:辉光管典型的 #FF5F00,在深色 nav 底色上非常显眼,但不像霓虹绿那么"卡通"

确定方向以后,剩下的就是把一只辉光管画进 SVG 里。

3.2 SVG 里画一只会发光的玻璃管

Logo 的左侧是一个辉光管图标,关键结构:

  • 管身<rect rx="14"> 深黑填充 #111,模拟玻璃在暗背景下的通透感
  • 栅极横线:三条细线 <line stroke="#222">,对应辉光管内部真实的金属栅极
  • 发光字符:一个橙色 > 形状,用 feGaussianBlur 三重叠加做光晕
  • 玻璃高光:前景叠一层 <linearGradient>,从左上 15% 不透明度渐到右下透明
  • 底座 + 引脚:小黑长方形加三条金属立线,呼应辉光管的铜脚底座

效果示意

辉光管图标:管身、栅线、橙色 prompt 与光晕

顺便,@keyframes 动画笔者最初是写了的(光标闪烁、辉光管电压不稳的微抖),但 WordPress 里 logo 是挂成 background-image 用的,浏览器出于安全策略会关闭 SVG-as-image 里的脚本和 CSS 动画。动画写了也不会播放,干脆移除。

3.3 中英文做成"横排单行"

第一版 logo 笔者做成了上下两行——CN 标题 + EN mono 副标题。

结果接到 nav 里明显偏方——aspect 比只有 2.5:1,一个短胖的小块,看起来不像"品牌条",更像一个按钮。

改成单行横排以后立刻舒服了。

效果示意

单行横排 logo:辉光管与中英文同一行

3.4 Nav 整体配色跟 logo 对齐

Logo 画完以后,笔者把整个顶栏的配色重新设计了一遍,让顶栏和辉光管 logo 连成一体,避免出现「黑条上硬贴一张图」的割裂感:

  • 底色#0B0B0F → #15151B 线性渐变,和 logo 玻璃管身呼应
  • 菜单默认#CBD5E1 slate-300,字距 0.04em(中文菜单呼吸)
  • hover:文字变 #FF5F00 辉光管橙,底线 2px 橙色 + box-shadow 光晕
  • 当前页 active> mono 前缀 + 橙色文字 + 橙色底线常驻,呼应 logo 副标题里的 prompt 字符
  • 滚动态 .is-fixed:半透明深底 rgba(11,11,15,0.82) + backdrop-filter: blur(14px),让底下内容透上来

所有元素围着同一个主题(辉光管 + 终端 prompt + 暖橙)服务,顶栏整体上像从 logo 里延伸出来的终端 title bar,和「黑条上多挂一块牌子」完全是两种观感。

修改前

修改后

这一段大概是整次翻新里笔者最享受的,是现在真的可以根据自己的需求,和模型结对做深度品牌设计


4 正文排版:一行到底应该多宽?

字体定了,下面是中文技术长文的核心变量——行宽、行距、字号。这三个数字决定了长文读起来是不是累。

4.1 行宽锁在 42rem

中文的舒适扫视半径是一行 35–45 个字。按 17px 字号算,大约是 660–720px 宽。笔者用了 42rem ≈ 672px,配合两侧留白:

.k-main .details .article .content {
  max-width: 42rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  font-size: 17px;
  line-height: 1.85;
  letter-spacing: 0.02em;
}

注意 line-height 给到了 1.85。17px × 1.85 ≈ 31.5px 的行高,对中英混排+内联 code 的场景足够宽松。太紧会挤,太松会散。

段间距比行高还要再大一点——margin: 1.4em 0段落边界明显高于行距,读者扫的时候才能自然感受到"一个段落结束了"。这一点在 14000 字的长文里尤其重要。

4.2 标题给"装饰位"

标题只靠字号拉开距离是不够的。一个做法是给 H2 加一条 4px 的品牌色左竖线,H3 加一个带透明度的 # 前缀:

.content h2 {
  padding-left: 0.7em;
  border-left: 4px solid var(--brand);
  font-weight: 700;
}
.content h3::before {
  content: "#";
  margin-right: 0.4em;
  color: var(--brand);
  opacity: 0.6;
}

这样扫一眼就能看出层级。代价不过是几行 CSS。

4.3 给内联 code 一个底色

技术文里信息密度最高的东西,是那些用反引号标出来的术语:fsyncio_uringKV cachecheckpoint。它们如果没有视觉区分,基本就融进了普通文字里。

笔者的做法是底色+等宽字体+偏红的前景色:

.content :not(pre) > code {
  background: #f6f8fa;
  border: 1px solid #f0f0f3;
  border-radius: 4px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  color: #c7254e;
}

修改前

修改后

改完之后重新去看那篇 FAST 长文——KV cachecheckpointprefix KV 立刻从段落里跳出来。这种"扫读能看到关键词"的体感,是技术长文必须给读者的。


5 首页卡片:告别老气横秋的"盒子感"

老主题的首页文章列表,带着一股浓烈的 2015 年气息。直角边框、生硬的实线分割、和标题挤在一行的分类标签。就是缺乏现代 UI 的"呼吸感"。

这次翻新,笔者没有停留在修修补补,而是直接对卡片的整体视觉骨架动了刀:

  • 重塑层级与圆角:页面底色降级为 #fafafa,卡片保持纯白 #fff。配合微弱的 box-shadowborder-radius: 10px,卡片自然就从背景里浮出来了,不再依赖生硬的边框去框定边界。
  • 分类标签"上树":原本的分类标签(如"项目跟踪")和标题挤在一行,视觉焦点混乱。笔者直接用 position: absolute 把它做成带有品牌色投影的实心小胶囊,挂到了缩略图的左上角。
  • 缩略图与细节:缩略图统一锁成 16:9 比例并加上圆角。底部的元信息(日期、评论等)分割线,从抢眼的实线换成了低调的虚线(1px dashed)。标题字号也拉到 1.3rem 配合字重 700,让它在单栏布局里有足够分量。
  • 解除高度封印:老主题在布局上埋了几个硬编码的雷,给标题和内容区写死了固定高度。一旦标题换行就会被生硬截断。笔者直接用 height: automax-height: none 把这些封印全部解除,让内容自然撑开。

另外,为了统一视觉,缩略图被强制要求 16:9。

修改前

修改后

其实代码也就几十行,但改完之后,整个首页的观感立刻从"传统 CMS 列表"变成了现代化的阅读应用。


6 侧栏和页脚:做减法

老 WordPress 的侧栏像是 2008 年的产物。笔者的侧栏原本堆了 10 个 widget:作者卡、公众号、搜索框、最近评论、热门页面、分类、70+ 项的按月归档字号乱飞的标签云、友情链接……

按月归档这个东西,2026 年还有谁会点?笔者自己都不会。

这块最终的策略是:

  • widget 卡片化:每块独立白卡 + 1px 边框 + 小阴影,和主内容视觉统一
  • widget-title 做成"小标签":13px 小字号、字间距 0.08em、全大写、底部 2px 深色实线
  • 标签云字号锁死 12.5px:WP 自带的"按热度决定字号"那套审美收束掉
  • 归档和分类条目过多时限高 280px 内滚动:保留存在性,但不让它吃屏幕

背景直接翻成 #18181b 深色,文字 #d4d4d8 浅灰。视觉一下子收束了——读者滚到页底会有"这篇内容到这里结束了"的明确信号。


7 服务端调优:2C4G 凭什么 OOM?

前面六节都在折腾前端 CSS。但翻新到一半,笔者想起来一个偶尔发生的、极度不符合直觉的事实:一台 2 核 4G 的机器,经常莫名其妙 OOM,MySQL 被系统强杀。

说来惭愧,整个的 LNMP 后端是作者若干年前一键安装的,中间几乎没怎么动过。虽说整个环境已经不是什么现代化设施了,2C4G 虽然不是什么神兵利器,但也绝不该被这点流量击穿。既然笔者已经从当年无知的高中生成长起来了,就没有理由让这些参数在拖硬件后腿。

排版再好看,页面 502 了也没用。既然都进手术室了,后端也一并处理。

7.1 PHP-FPM:堵住内存漏水的口子

原配置 pm.max_children = 18,数字看着保守,但致命的是没有设 pm.max_requests

WordPress 的插件生态在内存管理上出了名的粗放。一个 PHP 进程刚启动时可能占 30MB,处理几百个请求之后不知不觉膨胀到 150MB 以上——内存碎片回收不掉,一路涨上去直到系统 OOM。

那在 4096MB 的物理内存里,PHP 到底能分到多少?笔者做了一次严格的内存预算:

开销项 预算
Linux 系统 + Nginx ~300MB
MySQL 峰值 ~850MB
其他自建服务(Gitea 等) ~200MB
系统 Page Cache(留给 Nginx 吐静态文件) ~600MB
剩余给 PHP 的预算 ~2146MB

按极端情况单进程 80MB 算,安全上限大约 $2146 / 80 \approx 26$ 个进程。最终配置:

pm = dynamic
pm.max_children = 25
pm.max_requests = 500

pm.max_requests = 500 ——一个 PHP 进程处理完 500 个请求后强制自杀,主进程重新孵化一个干净的新进程。从物理上斩断了内存泄漏的无序累积。 代价是第 501 个请求的访客多等几十毫秒的进程重启延迟,生产环境里完全可以忽略。

作为第一门语言是 Go 的开发者,看到 PHP 竟然还能自动经过请求数来杀进程,深表震惊。真的不知道前辈们究竟经历了什么……

7.2 MySQL 5.7:卸掉沙袋

原配置的 MySQL 可以用"营养不良还背着沙袋跑步"来形容。笔者翻了一遍 my.cnf,发现了三个典型问题:

performance_schema 是内存刺客。 这玩意是 MySQL 的性能监控表,一个博客站根本用不上。但它启动就会凭空吃掉近 400MB——在 4G 的机器上,这是要命的比例。

query_cache 是时代的眼泪。 老配置还开着 64M 的查询缓存。WordPress 这种高度动态的系统,表里更新一个瞬态数据,MySQL 就会瞬间锁住并清空相关缓存。高并发下,频繁的"锁-清空"循环反而引发排队卡顿。MySQL 8.0 已经直接把这个功能删了,说明官方自己也觉得弊大于利。

DNS 反向解析在浪费时间。 默认配置下 MySQL 会对每个连接的 IP 做反向 DNS 解析。本机直连的架构根本不需要这一步,网络一抖动就会导致连接无故卡顿数秒。

最终在 my.cnf 里做的调整:

[mysqld]
# 关闭性能监控,夺回 ~400MB
performance_schema = off

# 挤出来的内存喂给 InnoDB
innodb_buffer_pool_size = 512M

# 关闭查询缓存
query_cache_type = 0
query_cache_size = 0

# 斩断 DNS 解析等待
skip-name-resolve

# 降低磁盘 I/O 压力
innodb_flush_log_at_trx_commit = 2

关掉 performance_schema 之后,innodb_buffer_pool_size 终于有底气拉到 512MB。绝大多数查询直接在内存里命中,CPU 的 iowait 立刻降下来了。

innodb_flush_log_at_trx_commit = 2 需要单独说一下取舍:它让每次事务提交先写入系统缓存,每秒刷盘一次。如果宿主机突发断电,可能丢失最后 1 秒的事务。但对博客系统而言,这个微小风险换数倍写入性能的提升,笔者认为是划算的。

7.3 Swap:两害相权取其轻

原机器的 vm.swappiness = 0,意思是宁愿 OOM 也不碰硬盘。在纯数据库节点上这是对的,但在 Web + DB + 杂七杂八服务共存的混合型机器上,其实是个陷阱。

设为 0 的后果:一些长期休眠的"死代码"——比如几周没人访问的 WordPress 后台管理模块——死死霸占物理内存,真正需要内存的热路径反而挤不进来。

设为 10 的效果:Linux 在内存用到约 90% 时,把这些冷页面挪到 swap 里。腾出来的物理内存会被系统自动转化为 Page Cache。Page Cache 是 Nginx 吐静态文件的超级引擎——图片、CSS、生成的 HTML 缓存直接从内存飞出去。

vm.swappiness = 10

这是一种防御性策略。遇到极端突发流量,系统仍然可能短暂假死。但这总好过 OOM Killer 直接把 MySQL 砍掉,全站 502 还得人工干预。


8 后记:主次先于观感

所有改动加起来大约 800 行 CSS 加一轮服务端参数调优,笔者和 Claude Opus 4.6 结对,几个小时就做完。没有装任何新插件、没有换主题、没有加外部依赖。

改完之后把那篇 14000 字的 FAST 长文重新用手机和电脑各读了一遍。行距舒缓、KV cache checkpoint 这些术语从段落里自然浮出、段落之间有节奏。主观感受是——终于可以心平气和地读完自己写的东西了

笔者这波改下来,排版上最先动手的永远是把文章的主次说清楚;主次顺了,页面通常也就顺眼:

  • 正文是主角,所以它居中、窄列、字号合适、字距舒缓
  • 标题是分段路标,所以它有色条、有前缀、视觉重量明显高于正文
  • 术语是扫读的锚点,所以反引号 code 要给它底色和等宽字体
  • 卡片元信息是配角,所以低信息价值的项目就不该出现

对于人类修改,真的要很耗时间。现在和模型结对编程,它们全部落实成 CSS 规则和配置文件的修改、在一个十年老博客上推下去、顺便把几个响应式断点下的老 hack 和祖传参数一并修掉——就是一次完整的现代化翻新了,整个过程丝滑愉悦。

受限于笔者的背景和主题限制,目前的版本还有不少可以继续打磨的地方:顶栏搜索框没做、首页 Hero 没做、按年归档折叠没做。这些都需要动主题 PHP,属于"下一阶段"的工作。不如就直接更换为 Astro 或者 Hugo 的静态技术栈。

纯 CSS 加参数调优能做到的那一层,已经让这个 2015 年的博客在 2026 年看起来不那么尴尬了。这对笔者来说够用了。

如果有读者也在用"看起来有点年头"的 WP 主题,希望这篇能帮上忙。欢迎一起交流排版和调优的心得——这东西没有标准答案。欢迎读者反馈新的页面视觉感受。


9 附录:核心 CSS 模块清单

最终版的附加 CSS 按以下九个区块组织,每块都可以单独取用:

1. 设计令牌(变量)
2. 全站字体兜底
3. 顶部导航
4. 首页文章卡片
5. 侧栏 widget
6. 文章详情页
7. 页脚
8. 分页
9. 响应式

一些具体指标作参考:

参数
正文列宽 42rem ≈ 672px
正文字号 17px(移动 16px / 超窄 15.5px)
正文行高 1.85(移动 1.8 / 超窄 1.78)
正文字距 0.02em
段落间距 1.4em
H2 字号 1.5rem,字重 700,左 4px 色条
H3 字号 1.18rem,字重 600,# 前缀
首页卡片标题 1.3rem,字重 700
品牌色 #0084d1(相比 Kratos 默认 #00a2ff 稍深一档)
页面背景 #fafafa
卡片背景 #fff
页脚背景 #18181b

希望这些数字都能在中文技术长文的阅读体验里找到对应的"为什么"。

SPtuan

团子最大的愿望是度过平静的时光。 当前从事分布式存储研发工作。

0 0 votes
文章评分
Subscribe
提醒
guest

0 评论
最新
最旧 得票最多
Inline Feedbacks
View all comments