Files
codex-bot 2b3b3a1ae4
Verify and deploy Tabularium / verify-and-deploy (push) Successful in 5m47s
Expand document collections with Pretext tutorial and simplify library navigation
2026-10-28 13:42:51 +08:00

4.2 KiB
Raw Permalink Blame History

第十章:亲自验证性能机制

10.1 先把问题变成可观察的证据

本教程关心四件事:

  1. 首次准备是否调用 Canvas?
  2. 相同文本再次准备是否复用测量?
  3. 改变宽度做布局时是否继续调用 Canvas?
  4. 这些样本的预测高度是否与 DOM 相符?

下载脚本后,将它放进研究版本的 Pretext 仓库 tutorials/zh-CN/verify.cjs(按需新建目录),因为它以该位置查找 ../../src。

随文的 verify.cjs用真实 Chromium Canvas,在 measureText() 外包一层计数器,同时统计提交字符串的 UTF-16 码元总数。然后测试英文、中文、保留空白的文本。

实验不使用伪造的平均字宽。源码通过 Node 的 TypeScript 转换功能转换为浏览器模块;没有修改库实现。

10.2 第一次研究保存的结果

原始记录在 results.chrome156.json。环境为本机 macOS、Headless Chrome 156、DPR 1,设置 <html lang="en">,使用记录脚本中的命名字体及其回退链。三段文本都重复了 12 次,刻意让缓存效果可观察。

样本 字符串 length 首次 Canvas 次数 首次提交码元数 再次准备 Canvas 次数 变宽布局 Canvas 次数
英文 1,428 62 529 0 0
中文 408 53 67 0 0
保留空白、tab、软连字符 888 50 497 0 0

每段分别在 80、121、200、319、320、321、480、800px 下求高度,24 组结果与 DOM 高度一致。这只能证明这些样本的高度一致,不能证明所有语言与断行位置都完全一致。

10.3 怎样理解计时数据

预先准备后,每轮做 3,000 次宽度切换,热身后取 5 轮中位数。原始记录为:

样本 Pretext 布局总时间 DOM 改宽后立即测高总时间
英文 1.7ms 86.0ms
中文 1.5ms 57.8ms
保留空白等 6.3ms 93.9ms

这些数字展示“用已测宽度计算”与“改变 DOM 宽度后同步求几何信息”的成本差异。它们不包含 Pretext 首次准备成本,也不包含完整页面绘制。

这不是严谨的产品性能排名:样本很少且重复,固定先测 Pretext 再测 DOM,没有记录硬件与电源条件,短样本受计时分辨率影响,也没有与批量 DOM 测量对照。结果不应被宣传成“任意页面快几十倍”。更可靠的机制证据是调用次数和这组样本的结果核对。

10.4 复现方法

要求 Node 23.10+ 或支持 module.stripTypeScriptTypes(..., { mode: 'transform' }) 的较新 Node、Playwright,以及可用 Chromium。

为避免改动本仓库的依赖,在单独目录安装实验依赖:

mkdir -p /tmp/pretext-study-deps
npm install --prefix /tmp/pretext-study-deps playwright
/tmp/pretext-study-deps/node_modules/.bin/playwright install chromium

在本仓库根目录运行:

PLAYWRIGHT_MODULE=/tmp/pretext-study-deps/node_modules/playwright \
node tutorials/zh-CN/verify.cjs

默认打印 JSON,不覆盖已归档结果。若要保存本次输出:

PLAYWRIGHT_MODULE=/tmp/pretext-study-deps/node_modules/playwright \
node tutorials/zh-CN/verify.cjs --output /tmp/pretext-study-result.json

也可以通过 CHROME_EXECUTABLE 指定已安装 Chrome 的可执行文件路径;两种方式选一种即可。脚本只监听本机回环地址,结束后关闭服务器与浏览器。

脚本会检查 24 组高度、重复准备和布局的 Canvas 调用次数,以及行文本 API 与行数 API 的行数一致性。失败时返回非零状态。它不设置速度阈值,因为这种微型计时不适合承担性能回归门禁。

项目正式验证还要看 harness/README.md 与 harness/bench/README.md:区分新文本、已见文本、resize、生成行文本与最坏情况;同时处理浏览器自身缓存、JIT、GC 和跨轮噪声。本教程没有运行完整的固定浏览器 harness,也没有把 headless 结果当成其正式准确性基线。