Lighthouse的Accessibility评分不能等同语义结构合规,因其不检查<main>唯一性、<section>标题缺失、<nav>位置等核心结构问题,仅报告可见缺陷;需勾选全部四类并配置断言(如landmark-no-duplicate-main)才能全面检测。

为什么Lighthouse的“Accessibility”评分不能直接等同于语义结构合规
Lighthouse 的 Accessibility 分类确实会检查 <h1> 是否缺失、标题是否跳级、<img> 是否缺 alt,但它**不验证 <main> 是否唯一、<section> 是否带标题、<nav> 是否在 <main> 之前**——这些才是语义结构的核心扣分点。工具只报它“能看见”的问题,而 HTML 结构层级错位(比如 <main> 套在 <div> 里、<section> 没配 <h2>)往往被跳过。
常见错误现象:
– 页面跑出 92 分的 Accessibility,但 Lighthouse 的“结构化数据”项却标红“Multiple <main> elements found”
– <header> 里塞了两个 <h1>,Lighthouse 不报,但 axe DevTools 和 W3C Validator 都会明确提示
- 真正影响语义结构评分的是 Lighthouse 的
SEO和Best Practices分类里的子项,比如 “Document doesn’t have a<main>element” 或 “<h1>is not the first heading” - 必须勾选全部四个类别(Performance / Accessibility / Best Practices / SEO)才能触发结构类检查,单选
Accessibility会漏掉关键项 - 本地跑分时若用
lhci autorun,默认 assert 不含结构断言,需手动加"document-has-main-element": ["error"]这类规则
如何用Lighthouse快速定位语义结构硬伤
不是所有结构问题都藏在报告末尾的“建议”里;有些是直接写进“诊断”(Diagnostics)面板的红色条目,得主动翻。
重点关注以下几条诊断信息:
– Document does not have a main landmark
– Heading elements are not in a logical order
– Page has no <code><h1> element
– Links do not have a discernible name(常因 <a> 里只有图标没文字或 aria-label)
立即学习“前端免费学习笔记(深入)”;
Google索引API工具。用于提交URL以供Google索引。支持两种模式:“auto-index”(获取sitemap,与缓存对比差异并提交...)
- 打开 Chrome DevTools → Lighthouse → 点击“Options”展开高级设置,务必勾选
Emulate mobile device和Clear storage,否则缓存 DOM 可能掩盖嵌套错误 - 跑完后不要只看总分,直接点开“Diagnostics”折叠面板,Ctrl+F 搜索
main、header、section,比扫“Opportunities”更高效 - 如果页面用了 SSR 或 hydration,确保 Lighthouse 启动时 JS 已执行完毕,否则
<main>可能还在<div id="app">里没提升出来——可在 collect 阶段加"waitFor": "document.querySelector('main')"
Lighthouse CI 中如何让语义结构问题真正卡住构建
默认 lhci autorun 只生成报告,哪怕 <main> 缺失、<h1> 错位,CI 依然绿灯放行。必须靠显式断言强制拦截。
在 .lighthouserc.json 中,至少要声明这些结构断言:
{
"ci": {
"collect": {
"url": ["http://localhost:3000"],
"numberOfRuns": 1
},
"assert": {
"assertions": {
"document-has-main-element": ["error"],
"heading-levels": ["error", {"minScore": 1}],
"html-has-lang": ["error"],
"landmark-one-main": ["error"],
"landmark-no-duplicate-main": ["error"]
}
}
}
}
-
heading-levels是 Lighthouse 内置断言名,检测跳级(如<h2>后直接<h4>),{"minScore": 1}表示必须 100% 合规,小数无效 -
landmark-no-duplicate-main比landmark-one-main更严格:后者只查是否存在一个<main>,前者查是否“没有重复”,能捕获 SSR 渲染残留的旧<main> - 如果项目用 Vue/React,
collect.waitFor必须设为真实 DOM 条件(如"document.querySelector('main').offsetHeight > 0"),否则断言在空壳 DOM 上运行,永远通过
结构走查中最容易被忽略的三个物理顺序细节
语义标签的书写顺序,比 class 名和 CSS 位置更重要。Lighthouse 不直接报“源码顺序错乱”,但会连带触发 Accessibility 项里的 “Focus order is not sequential” 或 “Heading order is not sequential”。
-
<nav>必须出现在<main>之前——哪怕视觉上它在页脚,HTML 源码也得提前写;用 CSSorder或flex-direction调整位置不算数 -
<section>内部第一个元素要是<h2>~<h6>,不能是<p>或<div>;空<section>直接算语义滥用,axe 会标 “sectionmust have a heading” -
<header>和<footer>可以嵌套,但每个<article>自带的<header>里只能有一个<h2>(内容级),不能混用站点级<h1>;否则 Lighthouse 的seo类别会警告 “Multiple<h1>elements”
结构走查不是找“有没有标签”,而是确认“标签是否在该在的位置、按该有的顺序、承载该有的语义”。一旦 DOM 顺序和逻辑流脱钩,再高的 Lighthouse 分数也救不了可访问性。


















