把只在特定页型出现的站点覆盖样式拆成页级包,由主题新增的按页型注入点加载;全站包从 43.5 KB 降到 29.6 KB,并用两道机械门证明每个页型的有效样式与拆分前逐字段一致。
上一阶段留下的选择
阶段 A 把 2016 行的单体 custom.css 拆成 29 个分片,但构建产物仍是一个文件、每个页面全量加载。这一阶段让「只在某些页型出现的样式」只在该页型加载。
拆分依据(先量后拆)
- 层叠零冲突:候选页级分片与全站分片的选择器零重合,候选之间也零重合。审计工具本轮修正了一个过严的冲突判据:原先「两组声明集合不同」即算冲突,会把「B 只是 A 的子集、同值」误报;正确判据是「同一属性被赋了不同值」。
- 跨页共用的规则组不撕开:
special-components.css一条选择器列表同时服务 changelog / gallery / 404 / privacy / ai-news / stats 六个页型,按页拆会把一条逻辑规则撕成六份换来每页几百字节,因此刻意留在全站包(改名components/special-pages.css)。
结构调整
规则简化为「目录决定加载范围」:
| 位置 | 加载范围 |
|---|---|
assets/css/custom.css | 全站(聚合根:@charset + 23 条 @import) |
assets/css/custom/{foundation,layout,components}/ | 全站(被聚合根内联) |
assets/css/custom/pages/<页型>.css | 只在该页型(文件名 = 主题的页型键) |
assets/css/custom/pages/post/*.css | 跟随 pages/post.css |
主题 styles.html 新增站点页级注入点(约 13 行,与主题自己的 pages/*.css 逻辑同构):按同一套页型键取 css/custom/pages/<键>.css,缺失即跳过,输出带 data-solitude-custom-page 标记;排在 css/custom.css 之后,保证站点覆盖层最后生效。页级包内部用 @import 组合、构建期内联,因此每个页型最多只多出一个 <link>。
验收中发现并修掉的一个真回归
静态门(下节)抓出:pages/post/tags.css 里三条规则的选择器列表把「文末标签」和「移动端侧栏标签云」写在了一起 ——
侧栏标签云在每个页面都存在,把整个分片划给文章页会让非文章页的移动端侧栏标签云掉样式。修法:按选择器把跨界规则拆开,全局部分独立成 components/tag-cloud.css(含 /tags/ 页的标签计数徽标),文章页分片只留 #post … 的部分。这是阶段 A 的分片边界留下的隐藏跨界 —— 当时按原文件的注释分区切分,而注释的粒度不等于作用域。
两道互补的机械门
按页加载只在两个方向会静默出事,各配一道门:
- 有效声明等价(改样式):对每个页型,把「该页实际加载的全部产物」与「拆分前的全量产物」展开到单选择器粒度,逐属性比对最终生效声明。
- 必须展开到单选择器:压缩器会把相邻同声明规则合并成多选择器规则,按规则键比对会误报。
- 必须产物比产物:压缩器会改写颜色/数值(
#ffffff→#fff),拿源码比产物同样会误报。 - 结果:文章页 392 个单选择器 / 关于页 323 / 留言板 326 / 其它页型 317,声明不一致均为 0;「仅拆分前有」的全部是该页不该加载的页级包。
- 不丢样式(丢样式):逐个已构建页面检查「该页含某页级包选择器所需的类名/id,却没有加载该包」—— 判据取源码侧规则(含
@media上下文),对每个页面 × 桌面/移动两种视口核验。结果:0 处。
外加工具侧不变式:node scripts/css-split-audit.mjs 现在会展开每个页级包的 @import 链,检查空包、与全站包冲突、页级包两两冲突。之所以必须零冲突 —— swup 无刷新切页时样式表只增不减,访问过文章页再切到关于页,pages/post.css 会一直留在 DOM 里;一旦有冲突,同一个页面的样子就会随「你从哪一页走过来」而变。
收益
| 页型 | 之前 | 之后 |
|---|---|---|
| 首页 / 归档 / 标签 / 友链 / 说说 / 音乐 / 隐私 / 统计 / 404 / 更新日志 / 相册 … | 43.5 KB(1 个请求) | 29.6 KB(1 个请求) |
| 文章页 | 43.5 KB | 29.6 KB + 11.7 KB(2 个并行请求) |
| 关于页 / 留言板 | 43.5 KB | 29.6 KB + 1.0 KB / 1.3 KB |
首屏渲染阻塞 CSS 在绝大多数页型上减少约 14 KB。
其他
- 审计工具新增
expandCssFiles/auditPageScope/splitSelectorList/explodeDeclarations,测试 39 → 47 pass。 - 构建 0 error;CI 双产物断言通过;样式分片审计
[ok];主题页级 CSS 与本轮改动零冲突。


