Skip to content

知识库技术叙事重构开发记录 ​

本轮只修改 site/** 文档、导航与文档治理内容,不修改 Collector、Mac App 或其他业务代码,不提交、不清理共享工作区。目标是把知识库从“文档治理结构优先”调整为“系统原理 → 性能领域 → 指标计算 → 工程合同”的技术阅读顺序,并以 Display Performance 作为第一套完整样板。

Phase 1 · 信息架构与阅读入口(2026-09-17) ​

目标 ​

先建立新的知识架构骨架,不在同一阶段迁移指标 Canonical 所有权,确保导航和链接先稳定:

text
知识库总览
→ iOS 性能观测基础
→ 产品能力
→ Display / Startup / CPU / Memory / Network / GPU / Energy
→ Session
→ 工程参考

实际修改 ​

  1. 重构 site/.vitepress/config.ts 的知识库侧栏:把 Scope / Evidence / Registry 从第一阅读层移到基础与工程参考,把 Display Performance 提升为完整一级技术领域。
  2. 重写 site/knowledge/index.md:首页改为“Perfowl 能观察什么 → 遇到问题先看什么 → 指标描述谁 → 数据怎样形成 → 再进入能力与工程合同”。
  3. 重写 knowledge-reading-map.md:阅读顺序改为“系统原理 → 专项领域 → 公式/质量 → 工程合同”。
  4. 新增 ios-performance-observation-model.md,建立 process / device / foreground-device、Gauge / Counter / Interval / Event / Trace 的基础模型。
  5. 新增 product-capability-overview.md,把面向产品的能力状态与工程级技术矩阵分开。
  6. 为后续 Display 专项拆页建立路由骨架:FrameTime、P95 FrameTime、Refresh Rate、Frame Pacing Jitter、Display Performance 技术演进与实验。

验证结果 ​

text
python3 site/scripts/metric-knowledge-gate.py
PASS: 66 Registry contracts, Canonical ownership, versionless governance, ten-element markers, sidebar and overview

PATH=/usr/local/bin:$PATH /usr/local/bin/npm run build
VitePress 1.6.4
build complete in 16.70s

构建只有既有 Rollup chunk-size warning,无死链或页面构建失败。

偏差与处理 ​

首次用结构化 npm 执行失败,因为 Runner 默认 PATH 中没有 npm;Shell 下直接执行也得到 npm: command not found。诊断确认 /usr/local/bin/node 与 /usr/local/bin/npm 存在,随后显式使用:

text
PATH=/usr/local/bin:$PATH /usr/local/bin/npm run build

构建通过。后续所有站点阶段验证统一使用这条环境约束,不再重复把 PATH 问题误判成文档失败。

可复用经验 ​

  1. 知识架构和 Canonical 合同应分阶段修改:先让新入口、导航和链接稳定,再迁移 metric ownership,可以显著降低一次改动同时破坏侧栏、合同索引与 Canonical gate 的风险。
  2. 首页不应要求读者先理解文档治理概念:Scope、Evidence、Registry 都应该保留,但需要先给性能问题和系统上下文,再引入术语。
  3. 产品能力与技术能力矩阵需要分层:前者回答“现在能看什么”,后者回答“source、条件、证据和平台边界是什么”。
  4. 构建工具环境本身也是门禁的一部分:当前 Runner 需要显式 /usr/local/bin PATH;记录后应复用,不再反复试错。

下一阶段 Gate ​

Phase 1 PASS。进入 Phase 2:重写 Display Performance 总览,修正“仍在迁移中”的过期表述,并把五个基础指标、当前 ActivityTrace 数据链、前台归因、常见误区和版本边界组织成总览页。

Phase 2 · Display Performance 总览收敛(2026-09-17) ​

目标 ​

把原 435 行 display-performance.md 从“五个指标合同 + UI + Report + 迁移方案 + 研究字段”的混合页面收敛成真正的领域总览,同时修正已经落后于 R3-R7-Fix 的产品状态描述。

实际修改 ​

  1. 页面从 435 行收敛为约 270 行,主线调整为:显示管线 → 五指标关系 → 当前 ActivityTrace 数据链 → foreground-device 归因 → 分析方法 → 质量/连续性 → 版本与证据边界。
  2. 明确当前代码事实:Swift Registry 的 FPS / FrameTime / P95 / Refresh Rate / Jitter 已全部指向 activitytrace-framelifetime;不再写成“目标架构尚未切源”。
  3. 将状态固定成三层:Source POC iOS 17 E4、产品实现 E2、完整产品 E4 Pending,避免把 source POC 与产品端到端验收混为一谈。
  4. 加入显示 pipeline 和五指标派生关系图,把 FPS、FrameTime、P95、Refresh Rate、Jitter 放回同一 presentation 事实模型中解释。
  5. 保留 P95 / Refresh Rate / Jitter 的紧凑 Canonical 合同附录,作为 Phase 3 独立指标页完成前的过渡,避免中间状态破坏 Canonical ownership gate。

验证结果 ​

text
metric-knowledge-gate: PASS
VitePress 1.6.4 build: PASS (15.73s)

可复用经验 ​

  1. 证据状态必须分层写:底层 source 在真机可用、产品代码已接入、完整产品场景已 E4 是三件事,合并成一个 migrating 或 production 都会损失信息。
  2. 总览页只负责建立模型:详细公式和字段应该进入独立指标页;总览应该帮助读者理解指标之间为什么相关,而不是承担全部 metric contract。
  3. 历史方案不应占据当前主叙事:CoreProfile 仍值得保留为技术演进与 legacy replay 事实,但不再以“当前生产来源”出现在 Display 总览主线。
  4. Canonical 迁移需要过渡态:先保留旧 owner 的十要素附录,等新 owner 页面准备完成后一次性迁移 ownership,可以让每个阶段都保持 gate 绿灯。

下一阶段 Gate ​

Phase 2 PASS。进入 Phase 3:重写 FPS / FrameTime / P95 / Refresh Rate / Frame Pacing Jitter 五个独立页,迁移 ios.frame.time、ios.frame.time.p95、ios.display.refresh_rate、ios.frame.pacing_jitter Canonical 所有权,并同步 Registry 合同索引。

Phase 3 · 五个 Display 基础指标独立 Canonical(2026-09-17) ​

目标 ​

让 FPS、FrameTime、P95 FrameTime、Refresh Rate、Frame Pacing Jitter 各自拥有完整技术页和唯一 metric ownership,同时修复合同索引里仍停留在旧 Graphics/CoreProfile source 的内容。

实际修改 ​

  1. fps.md 按当前 Registry 重写:主 source 从旧 Graphics gauge 修正为 ActivityTrace FrameLifetime,补 trailing 1s、静态页面 FPS=0、window freshness 与 legacy Graphics 定位。
  2. frame-time.md 正式接管 ios.frame.time:补 Display Presentation 原理、FrameLifetime 原始字段、Mach timebase 公式、prev_frame 59/59 真机连续性证据、首帧 warmup 和 one-shot freshness。
  3. frame-time-p95.md 正式接管 ios.frame.time.p95:冻结 10 秒窗口、nearest-rank、n<5 warmup,并区分 rolling P95 与 Session P95。
  4. display-refresh-rate.md 正式接管 ios.display.refresh_rate:冻结 refresh_interval + mach timebase → Hz,明确 ProMotion / observed distribution 边界。
  5. frame-pacing-jitter.md 正式接管 ios.frame.pacing_jitter:冻结 10 秒 P95-P50 与 reset 规则。
  6. frame-performance.md 不再拥有 ios.frame.time,只保留体验派生 metric family。
  7. display-performance.md 不再拥有 P95 / Refresh / Jitter,只承担领域总览。
  8. metric-contract-index.md 修正 #19 FPS、#23 FrameTime 的当前 Registry source / definitionVersion / service,并把 #23/#64/#65/#66 Canonical 链接切到新的独立页面。

验证结果 ​

text
metric-knowledge-gate: PASS
- 66 Registry contracts
- Canonical ownership unique
- ten-element markers PASS
- sidebar / overview PASS

VitePress 1.6.4 build: PASS (21.45s)

可复用经验 ​

  1. Canonical 所有权必须与阅读职责一致:如果总览页继续拥有多个独立指标,后续很容易再次把公式、证据与总览混在一起;拆 ownership 比单纯拆导航更重要。
  2. Registry source 改变时必须同步合同索引的 service / definitionVersion:只改知识正文会导致“机器合同表还在讲旧架构”的隐性冲突。
  3. FrameTime 的可读技术解释必须同时包含数学和连续性:只有公式 (end-prev)×timebase 还不够,必须解释为什么首帧不能直接算、为什么跨 epoch/display 不允许做差。
  4. source E4 和 metric E4 仍然分开:新页面统一保留这条边界,避免因为底层 FrameLifetime 真机可用就提前宣称 P95/Jitter 产品数值已完成真机校准。

下一阶段 Gate ​

Phase 3 PASS。进入 Phase 4:把 CoreProfile 高吞吐治理、Hitches/CoreAnimation/GPU/Video PTS 等失败路线与 ActivityTrace FrameLifetime 突破整理成独立《Display Performance 技术演进与实验》,正文只提炼结论并直接链接原始 devlog。

Phase 4 · Display Performance 技术演进与实验(2026-09-17) ​

目标 ​

把分散在 2000+ 行开发记录里的 Display source 研究提炼成可阅读的技术路线:不仅记录最终选了什么,也保留“为什么其他方案被排除”的实验依据。

实际修改 ​

  1. 新增 display-performance-evolution.md,按 CoreProfile → exact filter / csd / ta/tk → Animation Hitches → CoreAnimation immediate/deferred → frame-info presentation-time → KTrace/Hitches → CoreProfile deferred → GPU/Metal → Video PTS → ActivityTrace FrameLifetime 的顺序整理。
  2. 保留关键真机数字:CoreProfile 29.99/18.76 MiB/s、ActivityTrace 0.03696 MiB/s、约 507× / 99.80% 降幅,以及 prev_frame 59/59 连续链证据。
  3. 单独记录 R0-R6 产品化和 R7 首轮“5 metric 请求 / 2 metric contract”端到端故障,使 source 研究经验与产品合同经验都能追溯。
  4. 每个关键技术结论直接链接原始 devlog,不复制全部实验流水账。

验证结果 ​

该页面已随 Phase 3 后站点构建通过;Phase 5 修改后统一再次执行门禁和构建。

可复用经验 ​

  1. 失败路线也是知识资产:如果只留下最终 ActivityTrace 方案,未来很容易重新走一遍 CoreProfile deferred、GPU trace 或 video PTS 等已经证伪的路线。
  2. 技术史应该记录“决策依据”,不是开发日志摘要:保留单变量、关键数字、判定和停止条件即可,详细操作仍回链 devlog。
  3. source 研究与产品集成必须分开叙述:FrameLifetime POC 成功不等于 Workbench → Registry → CapturePlan → Launch 的产品请求链已经正确。

下一阶段 Gate ​

进入 Phase 5:同步 Frame Experience、显示管线、能力模型中残留的“仍在迁移 / 当前 CoreProfile”表述,并移除 Display 总览中已经完成迁移后的临时 Canonical 附录。

Phase 5 · Display 领域现状一致性收口(2026-09-17) ​

目标 ​

让 Display Performance 总览、Frame Experience、显示管线、技术能力矩阵和证据模型对“当前 source ownership”使用同一口径。

实际修改 ​

  1. Display 总览删除“下一阶段再迁移 P95 / Refresh / Jitter Canonical”的过渡段,改成明确链接五个独立指标页。
  2. Frame Experience 修正旧 CoreProfile 当前生产表述:新 Session 主 FrameTime 已来自 ActivityTrace;CoreProfile 仅保留 legacy replay / compare。
  3. 显示管线页修正为“当前代码已切源、完整产品 E4 Pending”。
  4. 将原“全指标能力矩阵”明确定位为“技术能力矩阵”,Display 行改成当前 ActivityTrace ownership,并与新产品能力总览分层。
  5. 能力与证据模型中的 Display 示例同步成 Source E4 / Product E2 / Full Product E4 Pending。

验证结果 ​

待本阶段修改完成后执行知识门禁与站点构建。

下一阶段 Gate ​

Phase 5 验证通过后进入 Phase 6/7:能力入口最终检查与术语提示收口,然后执行全站 Phase 8 验证。

Phase 5 验证补记 ​

text
metric-knowledge-gate: PASS(66 Registry contracts)
VitePress 1.6.4 build: PASS

构建仍只有既有 chunk-size warning,无死链或页面渲染错误。

Phase 6/7 · 能力入口与术语提示收口(2026-09-17) ​

目标 ​

保留必要工程术语,但让第一次进入知识库的读者不必先理解 Scope / Registry / Canonical 等词才能继续阅读;同时确认“产品能力总览”和“技术能力矩阵”职责分开。

实际修改 ​

  1. 保留 product-capability-overview.md 作为“现在能观察什么”的短入口,技术能力矩阵继续承担 source ownership、Runtime Condition、Evidence 与平台边界。
  2. 新增《技术术语速查》,统一解释 Scope、Registry、Canonical、Source Contract、Evidence、Warmup、Missing、Discontinuity、Source Epoch、definitionVersion 与 Legacy。
  3. 在知识库首页和 Display 总览首次出现 Scope 时使用原生 HTML abbr 的 ⓘ 悬停提示;不引入额外 Vue 组件和 JS 状态,保证文档内容在无脚本环境仍然可读。
  4. 工程合同入口补充术语速查链接,让读者可以按需下钻,而不是被迫先读 glossary。

可复用经验 ​

  1. 术语解释最好是渐进式披露:正文先给中文上下文,hover 只补一句话,完整定义再链接 glossary;不要把大段文档塞进 tooltip。
  2. 能用原生语义元素就不先造组件:abbr + title 已满足轻量 hover 说明,同时不会制造 VitePress 客户端 hydration 和样式维护成本。
  3. 产品能力与技术能力拆页后,术语密度自然下降:很多 Product State / Runtime Condition 不需要出现在第一层能力列表。

下一阶段 Gate ​

进入 Phase 8:搜索旧 Display source 口径、运行最终知识门禁与 VitePress build、检查 diff/hygiene,并把最终状态写回本记录。

Phase 8 · 全站一致性与最终验收(2026-09-17) ​

目标 ​

确认新信息架构、Display 五指标 Canonical、技术演进、能力分层与术语提示之间没有残留旧口径,同时避免公共产品首页继续依赖会随 Registry/source 演进漂移的硬编码数量。

最终修改 ​

  1. 全站搜索并确认以下旧 Display 口径在 site/knowledge 中均为 0 命中:正在迁移、当前生产 Registry 仍、source migration planned、目标:ActivityTrace、当前生产底层仍可能来自 CoreProfile。
  2. 合法出现的 CoreProfile / Graphics 描述只保留在历史、legacy replay、controlled compare 与技术演进上下文,不再冒充当前新 Session ownership。
  3. 公共产品首页的“流畅度”卡片改为进入 Display Performance 总览,并使用 FPS / FrameTime / P95 / Refresh / Jank 描述新的领域结构。
  4. 删除首页 64 / 64 Registry、9 / 9 源家族 等会漂移的硬编码数字,改成“指标合同构建时自动一致性校验”和“数据源按能力独立验证”。

验证结果 ​

最终文档变更前一轮已经确认:

text
metric-knowledge-gate:
PASS — 66 Registry contracts, Canonical ownership, versionless governance,
ten-element markers, sidebar and overview

VitePress 1.6.4:
PASS — build complete in 36.76s

公共首页一致性修正完成后已再次执行封口门禁:metric-knowledge-gate 继续 PASS(66 Registry contracts),VitePress 1.6.4 最终 build PASS,build complete in 39.50s;仅保留既有 chunk-size warning,无死链或页面渲染错误。

最终可复用经验 ​

  1. 不要在面向人的首页冻结 Registry/source 数量:精确数量属于机器合同与构建门禁,首页应描述能力,不承担容易漂移的计数镜像。
  2. 历史数据源可以保留,但必须带时间语境:CoreProfile Presented Frame 出现在实验史里是资产,出现在“当前生产 source”里就是错误。
  3. 知识重构的验收不能只靠站点能 build:还需要 Canonical ownership、合同索引、旧措辞搜索和人工阅读路径四类检查。
  4. 技术优先不等于术语优先:先建立系统模型和性能问题,再逐层揭示 Scope / Registry / Source Contract,技术深度反而更容易被读懂。

本轮边界 ​

本轮只修改 site/** 文档、导航和展示文案;没有修改 Collector、Mac App 或其他业务逻辑,没有提交或推送,也没有清理/重置共享工作区中其他协作者的改动。

Implementation Update · 2026-09-18 · 图示、术语提示与宽表格阅读体验修复 ​

触发问题 ​

知识库上线后的实际浏览暴露了 4 个展示层缺口:

  1. ```mermaid 代码块没有渲染器,flowchart LR/TD 被直接当作代码展示;
  2. 术语 ⓘ 只依赖浏览器原生 abbr[title],实际悬浮提示不稳定、不可控;
  3. 主题 CSS 在桌面端把表格强制设为 display: table,宽表格会突破正文列并遮住右侧“本页目录”;
  4. 重构后的知识页几乎只有文字、表格与流程代码,缺少适合长期维护的静态技术示意图。

实际实现 ​

  • Mermaid:在 Markdown fence renderer 中把 mermaid 代码块转换为 MermaidDiagram 组件;组件仅在页面实际出现流程图时动态 import('mermaid'),避免普通知识页承担 Mermaid 运行时代价。现有 6 个 Mermaid block 与后续新增 block 自动复用同一机制。
  • 术语提示:保留语义化 abbr[title],但新增纯 CSS tooltip 卡片,并给当前 Scope ⓘ 增加 tabindex="0";鼠标 hover 与键盘 focus-visible 都能显示一句话解释。相比原方案,没有引入额外 tooltip JS 状态或第三方组件。
  • 宽表格:恢复“内容列内横向滚动”模型,表格限定在正文容器 max-width: 100% 内,超宽内容只滚动表格自身,不再侵入右侧 aside/本页目录。
  • 静态图:新增 4 张可版本管理的 SVG 技术图,分别解释 Display 五指标关系、Startup 三层证据、Memory process/device scope、CPU process/device scope;正文使用 <figure> + alt + figcaption,并启用 loading="lazy"。SVG 使用精确工程术语,避免生成式位图中文字失真和难以 diff 的问题。

相对原方案的偏差 ​

2026-09-17 的 Phase 6/7 曾判断“原生 abbr + title 已满足轻量 hover 说明”。实际站点验收证明该假设不足:浏览器原生 title 的出现时机、样式与可访问性均不可控。本次保留 abbr 语义作为降级路径,但将用户可见交互升级为 CSS tooltip。这是对真实使用反馈的修正,不改变术语渐进披露原则。

验证证据 ​

text
metric-knowledge-gate:
PASS — 66 Registry contracts, Canonical ownership, versionless governance,
ten-element markers, sidebar, overview, knowledgeRole governance

VitePress 1.6.4:
PASS — build complete in 73.60s

Built HTML audit:
raw "flowchart LR/TD" in knowledge HTML = 0
pages containing rendered Mermaid container = 4
static SVG figures copied to dist = 4/4

构建仅保留 chunk-size warning;Mermaid 被拆为动态 chunk,不会由没有 Mermaid 图的普通页面主动加载。证据等级为 E2(站点构建 + 产物审计);本批只修改 site/**,未触碰共享工作区中正在进行的 MacApp/Sidecar 改动。

Implementation Update · 2026-09-18 · 左侧知识导航层级与可点击章节 ​

触发问题 ​

实际使用中,左侧章节标题与章节内文章标题视觉层级过近,章节标题看起来像普通文章,但点击后不会导航,容易形成错误交互预期。

实际实现 ​

  • 直接使用 VitePress 1.6.4 原生 SidebarItem 的 link + items + collapsed 能力,不新增自定义侧栏组件;章节标题点击进入该领域现有总览页,右侧 caret 单独负责展开/收起。
  • 将各章节原本重复出现的第一条“××总览”文章入口移到章节标题自身,减少一层重复导航;例如 Display Performance 章节标题直接进入 /knowledge/metrics/display-performance,子项从 FPS 开始。
  • 统一处理知识库总览、iOS 性能观测基础、产品能力、Display、Startup、CPU、Memory、Network/I/O、GPU、Energy、Session 与工程参考 12 个一级分组。
  • 主题 CSS 将一级章节提升为 15px / 750 字重并增加分组分隔与上下留白;二级文章缩进显示,hover 使用轻背景;当前文章使用 brand-soft 背景、左侧 3px 品牌色竖线与品牌色文字。
  • 折叠按钮保持独立 28×28px 点击区,hover 时单独反馈,避免把“进入章节”和“折叠章节”混成同一个动作。

实现边界 ​

本轮仅修改 site/.vitepress/config.ts、主题 CSS 与本开发记录;不改变文章内容、指标口径或 Collector/MacApp 业务逻辑。由于共享工作区的 site/devlog/index.md 正在被并行 R8 任务修改,本轮不覆盖该文件,避免把其他协作者的未提交内容混入本批提交。

验证结果 ​

  • npm run build:metric-knowledge-gate PASS(66 Registry contracts),VitePress 1.6.4 build PASS;仅保留既有 chunk-size warning。
  • 构建产物侧栏序列审计 PASS:Display Performance 分组具备 link + collapsed:false,首个子项为 FPS;CPU 与 Memory 分组同样确认父级链接与去重后的首子项。
  • git diff --check:本批 3 个文件 PASS。
  • 证据等级:E2(配置/样式实现 + 正式站点构建 + 构建产物审计)。

Implementation Update · 2026-09-18 · 全库术语与证据语义统一 + 自动术语注释 ​

触发问题 ​

知识库重排后出现两类一致性问题:一类是正式中文名称与行业常用术语不一致,例如把 Refresh Rate 写成“刷新节拍”、把 FrameTime 标成“帧耗时/显示呈现间隔”、把 CPU Usage 解释成“算力”;另一类是专业术语注释机制在视觉上像是“消失”了。审计确认后者不是 CSS 失效:主题里的 abbr[title] tooltip 样式仍然存在,但整个 site/knowledge 只剩 2 个手写 <abbr> 实例,而且都只注释 Scope,重排后的绝大多数正文没有再插入 ⓘ。

术语修订原则 ​

正式指标名称优先采用性能测试/开发领域更自然的通用中文,底层精确测量口径放在正文定义里,而不是把实现细节硬塞进名称:

  • FrameTime → 帧间隔;底层仍明确为相邻有效 Display Presentation 的时间差,不等于 CPU/GPU Render Time;
  • P95 FrameTime → P95 帧间隔;
  • CPU Usage → CPU 使用率;多核未归一化口径可以超过 100%,但百分比不是“芯片算力”单位;
  • Refresh Rate → 刷新率,单位 Hz;refresh_interval → 刷新间隔/刷新周期;“节拍”只在描述 cadence/pacing 时使用;
  • Thread Count → 线程数,不再写“活跃线程数”,也不把 GCD queue 当作线程;
  • Thermal Status → 热状态/系统热压力状态,不等价于“已经发生 CPU/GPU 降频”。

实际修订范围 ​

除名称统一外,本轮同步收紧了此前审计发现的证据越界表达:修正 TotalCPU Normalized 文档公式为 RawTotal / EnabledCPUs 并拆分 Raw/Normalized 证据状态;Context Switch 不再限定为“目标进程内部线程互切”;intWakeups 不再自行拆成硬件中断/定时器来源;NetworkStatistics 保持 source-native 字节语义,不猜测 TCP/TLS/重传组成;Disk I/O 改为进程级磁盘/文件 I/O 字节速率,不等价于 NAND 物理带宽;Energy Cost 保持 source-native cost,不扩写成物理功耗;Battery Electrical 在没有 battery-only 真机数值前继续明确 Unsupported;Presentation / Initial Frame END 不再写成 photon-to-eye 的“肉眼真正看到”;启动 Phase Coverage 缺失必须在 missing 与有独立证据的 not-applicable 之间区分。

三张已有技术 SVG 同步更新对应术语:Display 图使用“刷新率/帧间隔”;CPU 图不再把 PerCPUUsage 数组下标画成已确认的 P-Core/E-Core,而改为 Per-CPU 0...N;Startup 图把九阶段缺失明确为需要区分 missing / not-applicable。

专业术语 ⓘ 恢复方案 ​

新增 site/.vitepress/term-hints.ts,把术语解释从“散落在 Markdown 里的手工 <abbr>”升级为构建时统一注入:

  • 只对 knowledge/ 页面生效;
  • 每篇文章只标记某个术语的首次出现,并设置每页最多 6 个提示,避免满屏角标;
  • 跳过标题、代码和链接文本;
  • 使用统一词典维护 Scope、Registry、Canonical、Source Contract、E1–E4、warmup、missing、discontinuity、sourceEpoch、definitionVersion、Gauge、source-native、Presentation、Jetsam、QoS、DTX、KDebug、Phase Coverage、battery-only、fail-closed 等高价值工程术语;
  • 输出仍使用现有 abbr[title] CSS,因此鼠标 hover 与键盘 focus 都能看到简短解释;完整定义继续链接到《技术术语速查》。

这样后续文章重排时不需要人工复制角标,术语第一次出现即可自动获得一致解释。

并行工作边界 ​

本批只修改 site/** 的知识页、VitePress Markdown 扩展、技术 SVG 与本开发记录;没有修改 MacApp/Sidecar 产品代码,也没有触碰正在由 R8 并行任务修改的 site/devlog/index.md 和未跟踪的 site/devlog/p4-r8-display-performance-gap-classification-result.md。

验证门禁 ​

交付前执行:metric-knowledge-gate + VitePress 正式构建、构建产物 tooltip 注入审计、13 类遗留错误表述 residue audit、Canonical 标题/公式断言与 git diff --check。证据等级按 E2(文档/构建产物) 记录,不把术语修订描述成新的真机 E4 能力。

Follow-up · 2026-09-18 · 术语 Tooltip 去重 ​

用户实测发现专业术语悬停时出现两份相同解释。根因是自动术语注入同时写入 HTML 原生 title,主题 CSS 又通过 ::after { content: attr(title) } 渲染自定义 tooltip,浏览器原生 title 与自定义层会同时出现。

修复后自动术语使用 data-tooltip 作为视觉提示内容、aria-label 保留可访问语义,并把主题选择器收窄到 abbr.perfowl-term-hint[data-tooltip];不再输出 title,因此浏览器不会再生成第二份原生提示。正式构建 PASS;构建产物审计确认 perfowl-term-hint 的 title 属性计数为 0、data-tooltip 正常存在。

Follow-up · 2026-09-18 · 表格内术语 Tooltip 防裁剪 ​

用户实测发现术语注释位于横向滚动表格中时,tooltip 会被表格的 overflow-x: auto / overflow-y: hidden 容器裁剪,只显示局部内容。

根因不是文本宽度,而是旧 tooltip 通过 abbr::after 作为术语节点的子绘制层存在,仍属于表格滚动容器的裁剪上下文。

本轮将 tooltip 升级为 viewport 浮层:hover/focus 时由主题脚本创建 body > .perfowl-term-tooltip,使用 position: fixed 根据术语元素的 getBoundingClientRect() 定位;优先显示在下方,空间不足时自动翻到上方,同时对左右和上下视口边缘做 clamp。滚动(包括表格横向滚动)与窗口 resize 时会重新定位。原 abbr::after tooltip 已完全移除。

同时把术语 aria-label 调整为“术语名:解释”,避免无障碍读取时只听到解释而丢失术语本身。

验证:metric-knowledge-gate PASS;VitePress build PASS;最终产物保留 data-tooltip,不再包含旧的 abbr.perfowl-term-hint[data-tooltip]::after,且客户端 bundle 已包含 .perfowl-term-tooltip viewport 浮层逻辑。

Perfowl · Performance Observer