*会让recalculate style时间飙升,因为浏览器从右向左匹配时需逐个检查所有dom节点(含script、meta、注释、伪元素等),无法索引或剪枝,强制重算每个节点的继承值,并放大后续选择器匹配开销。

为什么 * 会让 Recalculate Style 时间飙升
浏览器匹配 CSS 是从右往左的,* 没有索引、无法剪枝,只能逐个检查每个 DOM 节点——包括 <script></script>、<meta>、注释、甚至伪元素生成的节点。哪怕它只写在重置文件末尾,浏览器也得为每个节点确认是否被它覆盖。
- 无法复用已计算的继承值:比如
html { font-size: 16px; }本可自然继承,但* { font-size: 14px; }强制重算每个节点 - 后续同级选择器变慢:浏览器得先排除
*干扰,才能缓存匹配结果 -
*::before更糟:一个元素 → 生成两个伪节点 → 实际匹配目标翻倍;500 个节点可能变成 1500+ 次匹配
* { box-sizing: border-box; } 看似无害,实则高危
这条规则常被当作“最佳实践”塞进 reset.css,但它在 DOM 节点超 500 个时,极易让 Recalculate Style 阶段突破 20ms,直接卡住首次内容绘制(FCP)。
- 它不只影响容器类,而是强制扫描所有节点,包括
<svg></svg>、<canvas></canvas>、<textarea></textarea> -
<input type="text">失去默认内边距,点击区域收缩,移动端难触发 -
<select></select>高度塌缩,下拉箭头错位;<svg></svg>图标被压缩变形,viewBox失效 - 第三方组件(如
react-datepicker)依赖默认 margin 布局,一加*,弹窗立刻偏移
*[data-tip] 这类组合比单个 * 更伤性能
属性选择器本身不慢,但和通配符嵌套后会放大问题。比如 *[data-tip] 或 div * [type="text"],浏览器必须遍历全部节点再逐个检查属性是否存在/匹配。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
-
[type="text"]单独用,开销≈.input;但form div * [type="text"]在 500 个同级<input>上 layout 耗时可跳到 4.7ms+ -
[data-*]无底层索引,匹配全靠遍历;[style*="color"]更危险——每次内联样式变更都会触发整条选择器重算 - SVG 中的
[fill]、[d]同样无索引,应改用 class 控制状态
真正可用的替代方案,不用改 HTML 结构
别急着删已有 *,先用 DevTools Performance 面板录首屏加载,看 Recalculate Style 是否占高比例;再用 Coverage 工具查哪些 CSS 实际未被使用。替换不是一刀切。
- 用
:where()降权 + 语义类名::where(h1, h2, p, ul, li) { margin: 0; padding: 0; } -
box-sizing只作用于容器类:.container, .card, .form-group { box-sizing: border-box; } - 禁用
user-select?只针对非文本区域:.no-select { user-select: none; } - 若必须基于
data-控制样式,优先用 JS 初始化时批量加 class,后续全走 class 匹配
最常被忽略的一点:性能问题往往不出现在选择器写法本身,而在于它迫使浏览器做更多 layout / paint。比如 .sidebar > .item:hover::before 触发非合成层绘制,比选择器多写几个层级更伤帧率。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










