html语义化标签用错等于没用,需确保标签与内容意图匹配;dom深度超6层会引发性能问题;模板引擎block继承需全局唯一命名;script放置位置直接影响首屏白屏时间。

HTML语义化标签用错就等于没用
很多开发者以为只要把 <div class="header"> 换成 <code><header></header> 就算语义化了,其实不是。语义化失效往往发生在标签与内容意图不匹配时。
常见错误现象:页面能正常显示,但 SEO 排名上不去、屏幕阅读器跳过关键区块、Lighthouse 的“结构化数据”项报红。
-
<section></section>必须带标题(<h2></h2>或更高层级),否则浏览器和爬虫会把它当普通<div> 处理 <li> <code><main></main>全页只能出现一次,且不能嵌套在<article></article>、<aside></aside>或<nav></nav>内部 -
<aside></aside>不是“右边那个 div”,而是指与当前<article></article>相关但可独立分发的内容(如引用来源、术语解释) - 连续多个标题(比如主标题+副标题)应包在
<header></header>里,而不是并列放两个<h1></h1> - SSR 输出的
<div id="app"><div class="page"><div class="container">…</div></div></div>—— 实际只有一处用到container类 - 表单控件外三层包裹:
<div><div><div><input></div></div></div> - 卡片组件命名式嵌套:
card-wrapper → card-inner → card-body → card-content - block 名必须全局唯一且语义明确,例如
'header-nav'、'main-hero'、'sidebar-recommend' - 所有 block 名应在项目根目录统一维护成 JSON 配置,供构建脚本校验
- 避免超过三层继承(
layout → inner → feature已够用),再深会导致编译缓存命中率骤降、调试困难 - 核心业务逻辑(如路由初始化、状态预载)必须加
defer,保证按顺序执行且不阻塞 DOM 构建 - 统计、广告、埋点等无依赖脚本用
async,但别指望它们加载完再操作 DOM - 内联脚本默认阻塞,除非你写了
type="module"(此时自动defer) - 千万别在
里混写<link rel="stylesheet">和没加defer的<script></script>,这是首屏性能杀手
DOM 深度超过 6 层,渲染性能就开始失控
不是节点多才慢,是嵌套深才卡。Chrome DevTools 的 Layout 阶段耗时会随深度非线性上升,尤其当 JS 调用 getBoundingClientRect() 或读取 offsetHeight 时,极易触发强制同步布局。
典型诱因是模板引擎或手写代码中为“撑样式”硬加的 wrapper:
压平的关键不是删标签,而是让 CSS 承担视觉结构:用 flex / grid 替代容器堆叠;图标+文字组合改用内联文本;分隔线用 ::before 伪元素而非空 <div>。
<h3>模板引擎里的 block 继承容易覆盖失效</h3>
<p>art-template、Nunjucks 等支持多层继承时,<code>{{block 'content'}} 命名冲突会导致中间层插入点彻底消失——你写了三处 block,最终只渲染最末一层。
真实使用场景:大型门户中 layout.art → inner-layout.art → page.art → detail.art,一旦某层重名,导航栏、侧边栏、主内容区全乱套。
<script></script> 放哪儿真会影响首屏白屏时间
哪怕只是 <script>console.log(1)</script> 放在 里,也会阻塞 HTML 解析,用户看到白屏的时间可能从 200ms 拉长到 2s 以上。
这不是“放底部就行”的问题,而是执行时机必须显式声明:
真正难处理的是那些既依赖 DOM 又不能延迟太久的脚本——它们得靠 DOMContentLoaded + requestIdleCallback 组合控制,而不是靠位置赌运气。











