候选 CSS 关键指标对照(ui-metrics.py)¶
位置:
deploy/nfos/tools/ui-metrics.py| 语言:python3 | 是否需要 root:否
工具性质:本地静态统计(只读多份 CSS;只写 --out 指定的文件)
运行前提:只需给全文件路径 —— 本工具不自动定位仓库根、不加载 lint-layout.py
部署状态:随仓库检出运行,不部署到 /opt/Cy/services/system.d/nfos/
用途¶
把「基线 / 并发版 / 候选 A(可选候选 B)」的关键指标拉成一张对照表(Markdown 表格)。
源码 docstring(逐字引用):
产物是一张 Markdown 表:行为指标、列为各版本文件,末三行为字节数、sha256 前 16、完整 sha256。
统计的 19 个指标(名称逐字来自源码 METRICS):
| 类别 | 指标 |
|---|---|
| 玻璃拟态/视觉 | backdrop-filter 次数、--nf-glass* 次数、--nf-aurora* 次数、radial-gradient 次数、--nf-glow-accent 次数、--nf-grad-accent 次数、box-shadow: 次数 |
| 主题令牌取值 | 主题底色 --nf-bg、主色 --nf-accent、圆角 --nf-radius(这三项带分组,输出为「取值 (N 处)」) |
| 显示完整性 | white-space:nowrap、text-overflow:ellipsis、overflow-wrap:anywhere、overflow-x:clip、width:max-content、min-width:0、max-height:min(...) 夹紧 |
| 动效 | animation: 次数、infinite 次数 |
实现要点:load() 读文件后用 re.sub(r'/\*.*?\*/', '', t, flags=re.S) 剥离注释;带捕获组的指标(--nf-bg / --nf-accent / --nf-radius)输出 取值 (N 处),其余只输出出现次数。
典型场景¶
- 在多个 CSS 候选(基线 / 并发版 / 候选 A / 候选 B)之间做取舍决策:一眼看到玻璃拟态、渐变量、动效次数与主题令牌取值的差异;
- 确认“候选 A 用基线头部合成”后,视觉类指标没有被意外放大或抹平;
- 与
ui-delta.py(改动前后对比)、ui-audit.py(显示完整性模式计数)联用:前者看显示完整性缺口,本工具看视觉/主题指标是否漂移。
用法与参数¶
源码 docstring 给出的用法(逐字引用,.scratch/ 为升级前旧路径;本页按新位置书写,路径参数不变):
用法:
python .scratch/ui-metrics.py --base <基线.css> --other <并发版.css> --candA <候选A.css> \
[--candB <候选B.css>] --out .scratch/ui-metrics.txt
参数来自 argparse.ArgumentParser():
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--base |
字符串(文件路径) | 无默认值(required=True) |
基线 CSS;表中列名为 基线 |
--other |
字符串(文件路径) | 无默认值(required=True) |
并发版 CSS;表中列名为 并发版(19:11) |
--candA |
字符串(文件路径) | 无默认值(required=True) |
候选 A CSS;表中列名为 候选A |
--candB |
字符串(文件路径) | ''(空 = 不加该列) |
候选 B CSS;给值时才追加列,列名为 候选B(未采用) |
--out |
字符串(文件路径) | ''(空 = 写 stdout) |
输出文件;给值时打印 written: <path> |
无参数时的默认行为:没有默认行为 —— --base / --other / --candA 三项必填,缺失时 argparse 报错并以退出码 2 结束。只有 --candB 与 --out 可省。
所有路径参数都按当前工作目录解析;本工具不做仓库根拼接,也不需要仓库检出(只要能读到传入的文件)。
示例¶
从仓库根目录执行(--base / --other / --candA 换成实际存在的文件名):
python deploy/nfos/tools/ui-metrics.py `
--base apps/web/index/css/nf.css `
--other .scratch/nf-css-concurrent.css `
--candA .scratch/nf-css-candidate-A.css `
--out .scratch/ui-metrics.txt
需要第四列时追加 --candB <候选B.css>。
期望输出形态:
落盘/标准输出的正文形如(Markdown 表格):
== 关键指标对照(统计前已剥离注释)==
| 指标 | 基线 | 并发版(19:11) | 候选A |
|---|---|---|---|
| backdrop-filter 次数 | 4 | 6 | 6 |
| 主题底色 --nf-bg | #0b1020 (1 处) | ... | ... |
| white-space:nowrap | 123 | 118 | 96 |
...
| 字节数 | ... | ... | ... |
| sha256 前 16 | ... | ... | ... |
| 完整 sha256 | ... | ... | ... |
| 情形 | 期望退出码 |
|---|---|
| 正常完成 | 0(sys.exit(main()) 且 main() 恒返回 0) |
缺 --base / --other / --candA |
2(argparse 报错) |
任一 CSS 路径不存在 / --out 不可写 |
1(Python traceback) |
指标数值差异不影响退出码:本工具只出表,不做任何断言。
依赖与权限¶
- 语言/版本:Python 3(
#!/usr/bin/env python3)。 - 第三方依赖:无,标准库
argparse/hashlib/io/re/sys。 - 仓库依赖:无 —— 源码没有
_nf_repo_root(),不加载lint-layout.py,所有输入都是命令行路径。(这是本批ui-*.py中唯一不依赖仓库根的工具。) - 权限:不需要 root;不需要网络(纯离线);写权限仅用于
--out。
风险与注意事项¶
- 只读输入,只写
--out:不修改任何 CSS。不传--out时只写 stdout(UTF-8 字节),不落盘。 - 指标是“出现次数”,不是视觉等效:例如
backdrop-filter 次数多 2 次不代表观感差异显著;box-shadow: 次数只数声明个数,不看层级与透明度。取舍仍需人工判断。 - 注释已剥离:统计前统一去掉
/* ... */。因此“被注释掉的旧写法”不会计入,这是有意设计(避免注释放大计数)。 - 带捕获组的 3 个指标取首次匹配:
--nf-bg/--nf-accent/--nf-radius用m.group(1)展示第一个匹配到的取值,若文件里同一令牌声明了多次(例如追加区块覆盖),表中显示的可能不是最终生效值;需要精确结论请用ui-keyrules.py。 --candB省略时不生成该列(不会输出空列)。- 输出是 Markdown:直接重定向到
.md附件或粘进报告都可用。
回滚¶
本工具不部署到线上、不改线上系统;不改动任何被统计文件。
- 产出/改动位置:仅
--out指定的文件(例如.scratch/ui-metrics.txt)。 - 清理方式:
- 不给
--out时无任何落盘物,无需清理;线上侧无需回滚。