autofocus 属性对首屏性能无影响,仅在 html 解析时触发一次聚焦;其在移动端、动态渲染及隐藏元素中常失效,应改用带校验的 js focus() 控制。

autofocus 属性根本不会拖慢页面加载
它对 FP、FCP、LCP 等首屏性能指标没有可测量影响。浏览器在 HTML 解析阶段只是“记一笔”,不触发 layout、不阻塞渲染、不执行 JS——整个过程发生在 DOM 构建完成后,完全游离于渲染流水线之外。实测开启/关闭 autofocus,DevTools Performance 面板中各项指标波动始终在 ±1ms 噪声范围内。
真正拉低用户体验的,是开发者发现它没生效后补的那些 JS 逻辑:useEffect(() => inputRef.current?.focus())、setTimeout(() => el.focus(), 100)、或反复轮询 document.activeElement。这些操作才可能引发强制同步 layout、重排、事件循环堆积,尤其在 modal 显示动画未结束时就调用 .focus(),很容易导致一帧卡顿。
它只在静态 HTML 解析那一刻起一次作用
autofocus 不是开关,不是事件监听器,也不是 JS 可重新触发的行为。它只在浏览器逐行读取原始 HTML 字符串时,对第一个符合条件的元素尝试聚焦;之后任何操作都不会让它复活:
-
document.body.innerHTML = '<input type="text" autofocus>'→ 完全无效 -
input.setAttribute('autofocus', '')或input.autofocus = true→ 不触发聚焦 - React/Vue 组件挂载后渲染的
<input autofocus>→ hydration 已完成,错过时机 - 页面从后台标签页切回、iframe 内加载、或 iOS Safari 中 → 大概率静默忽略
移动端和动态场景下它基本等于没写
iOS Safari 主动限制非用户手势触发的自动聚焦,防止软键盘意外弹出遮挡内容。这不是 bug,是 Apple 的明确设计策略。结果是:
- 首页
<input autofocus>→ 光标可能设了,但键盘不弹,用户无感知 - 模态框
show()后的autofocus→ 失效,除非聚焦逻辑包裹在onclick或ontouchend回调里 -
.focus({ preventScroll: true })能避免滚动抖动,而autofocus完全没这个能力 - 隐藏即失效:父容器
display: none、visibility: hidden、inert或tabindex="-1"→ 浏览器直接跳过该元素
该用 focus() 时别硬扛 autofocus
只要页面涉及 SPA、条件渲染、路由切换、模态框或移动端,就该放弃 autofocus,改用 JS 显式控制。但要注意三个关键校验点:
- 元素是否已挂载:
el && el.offsetParent !== null比getComputedStyle(el).display !== 'none'更准 - 是否可聚焦:
!el.hasAttribute('disabled') && el.tabIndex >= 0 - 是否在用户手势上下文中(尤其 iOS):
button.addEventListener('click', () => input.focus())才安全
最常被忽略的一点:即使 .focus() 成功,若元素正处在 CSS 动画中(比如 opacity: 0 或 transform: translateY(-20px)),焦点会静默失败——这种“视觉可见但不可聚焦”的状态,必须靠 requestAnimationFrame 延迟到下一帧再试,且要加重试上限,否则容易陷入死循环。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











