直接答案:25 个首页中 16 站成功渲染,9 站返回 403、挑战页或不足 2 KB,未计入。16 站里,aria-* 属性从静态 13 个增至渲染后 172 个(7 站)、role 从 3 增至 84、aria-hidden 从 1 增至 35(3 站);被 aria-hidden 覆盖的可 Tab 元素从 0 增至 4(2 站)、悬空 id 引用 0→5(1 站);H1 从 27 增至 29(2 站,1 站首次出现 H1);main 仍为 3/16,nav/header/footer 零变化;iframe 3→5,脚本 270→323(12 站增加、1 站减少)。
本文只比较静态 HTML 与 headless Chrome 序列化后的 DOM,不判断视觉、对比度或读屏播报。
方法:同一页面的静态与渲染后各数一遍
2026-11-09 01:45–01:48,对第 4 期 25 个缓存 200 首页先实时请求静态 HTML,再用 headless Chrome(--headless=new --dump-dom,虚拟时间 15 秒,每站独立 profile)取渲染后 DOM。两遍都用同一套解析器统计 landmark、H1、ARIA、可 Tab 元素与 id 引用,再逐项相减。
| 口径 | 定义 | 边界 |
|---|---|---|
| 渲染成功 | Chrome 输出含 <html>、超过 2 KB、不是错误页 | 403/挑战页不计为 0 |
| 可 Tab 元素 | button/input/select/textarea/summary、a[href];有 tabindex 时取 ≥ 0 | tabindex="-1" 不计 |
| ARIA 属性 | 序列化 DOM 中 aria-* 的数量 | 只读静态 DOM,不看运行时可访问性树 |
| 悬空 id 引用 | aria-labelledby/controls/owns 指向文档内不存在的 id | 只查文档内存在性 |
结果:ARIA 增加 159 个,地标零注入
| 指标 | 静态 | 渲染后 | 增加的站点 |
|---|---|---|---|
| 有 main | 3 站 | 3 站 | 0 |
| H1 总数 | 27 | 29 | 2 |
| 没有 H1 的站点 | 8 | 7 | — |
| aria-* 属性 | 13 | 172 | 7 |
| role 属性 | 3 | 84 | 7 |
| aria-hidden="true" | 1 | 35 | 3 |
| 被 aria-hidden 覆盖的可 Tab 元素 | 0 | 4 | 2 |
| 悬空 id 引用 | 0 | 5 | 1 |
| iframe | 3 | 5 | 2 |
| script | 270 | 323 | 12(1 站减少) |
增量高度集中。E02 从 209 KB 增至 1,410 KB(6.7 倍),ARIA 0→29、role 0→19、aria-hidden 0→9、可 Tab 覆盖 0→3、悬空引用 0→5;E11 的 aria-hidden 0→23,但 44 个后代都带 tabindex="-1",不在 Tab 序列,按口径不计;E25 从 287 KB 增至 464 KB,ARIA 6→11、可 Tab 覆盖 0→1。E18 静态没有 H1、只有 1 个脚本,渲染后出现 H1 和 1 个 iframe,体积 15.7→66.8 KB;E17 的 H1 从 2 增至 3、ARIA 7→33。
为什么这会影响验收
- 静态扫描低估 ARIA。 16 站里 92.4% 的 aria-* 属性(159/172)是渲染后才出现的;只看源码会漏掉整块。
- 最严重的问题只在渲染后出现。 4 个可 Tab 元素被 aria-hidden 覆盖、5 条悬空引用,静态结果都是 0。
- JavaScript 不补地标。 main / nav / header / footer 在 16 站全部零注入,main 仍是 3/16;H1 也只多了 2 个。
- 体积增长集中在少数站。 16 站合计从 1.23 MB 增至 2.79 MB,E02 一页就贡献 1.2 MB。
对验收的启示
- 语义验收跑两遍:静态 + 渲染后 DOM。 只看静态会漏掉 159 个 ARIA 属性与全部 4 个隐藏可 Tab 元素。
- 把 aria-hidden × 可 Tab 设为高优先级。 2 站共 4 个元素,键盘用户可能 Tab 进看不见的区域。
- 悬空引用要自动化。 5 条只在渲染后出现,手工抽查很难发现。
- 不要指望 JS 补 H1 与 landmark。 本轮只有 2 站补了 H1,地标零注入,模板问题仍需在模板层修。
- 渲染失败单列。 9 站 403/挑战页,不能当作“没有 ARIA”。企业官网验收可参考网站建设服务。
局限
- 16/25:9 站未渲染成功(403、挑战页、输出不足),已被排除,不作为 0。
- 渲染窗口:headless Chrome + 15 秒虚拟时间,晚于该窗口的异步内容看不到;没有交互,折叠菜单的状态可能与真实浏览不同。
- 可 Tab 是启发式:不执行真实 Tab 顺序,不计 iframe 内部与 shadow DOM;
tabindex="-1"不计。 - 只读 DOM:不判断读屏播报、对比度或焦点是否可见。
- 25 站 pilot:同一批装备企业样本,不外推行业。
数据与复算
匿名数据:equipment-homepage-rendered-dom-2026.csv(25 行 × 30 列:每个指标静态/渲染后计数、页面 KB、渲染是否成功与时间)。仓库内为 docs/research/2026-11-homepage-rendered-dom.csv。
解析:scripts/aria_probe.py、scripts/semantic_structure_probe.py 与 scripts/dom_delta.py;单测 test_content_aria_probe.py(16 项)、test_semantic_structure_probe.py(9 项)、test_content_dom_delta.py(5 项,均无网络)。运行:
python -m unittest scripts.test_content_aria_probe scripts.test_semantic_structure_probe scripts.test_content_dom_delta
配套:首页语义、键盘与 ARIA(静态口径)、首页焦点样式复测、首页链接结构 pilot。
数据来源与口径
- 样本:第 4 期 25 个缓存为 200 的首页。
- 静态:2026-11-09 01:45–01:48,串行实时请求,超时 15 秒。
- 渲染:headless Chrome
--dump-dom,虚拟时间 15 秒,每站独立 profile。 - 排除:9 站返回 403、挑战页或输出不足 2 KB。
- 口径:可 Tab = 自然可聚焦或 tabindex ≥ 0;aria-hidden 覆盖按祖先链判断。
常见问题
为什么只有 16 站?
25 站里有 9 站没有成功渲染:返回 403、挑战页或输出不足 2 KB。它们被单列排除,不当作“没有 ARIA”或 0 值。
ARIA 从 13 到 172,说明网站更无障碍吗?
不能这样说。数量不等于正确:同一批渲染结果里出现了 4 个可 Tab 元素被 aria-hidden 覆盖、5 条悬空 id 引用,这些是渲染后才暴露的问题。
JavaScript 会补 H1 和 landmark 吗?
本轮几乎没有:只有 2 站渲染后多了 H1(其中 1 站从 0 到 1),main / nav / header / footer 在 16 站全部零注入。
E11 的 44 个元素为什么不算被 aria-hidden 覆盖?
它们都带 tabindex="-1",不在 Tab 序列中。本文只统计键盘 Tab 能到达的元素,脚本聚焦另测。
tabindex="-1" 不是还能被 JS 聚焦吗?
是,程序化聚焦仍可行;但它不在键盘 Tab 顺序里,所以不计入本轮的“可 Tab”口径。
数据能复核吗?
可以。公开 CSV 25 行 × 30 列;scripts/aria_probe.py、semantic_structure_probe.py 与 dom_delta.py 共 30 项离线单测。