Back

框架之下:信任 Web 的原生能力

框架之下:信任 Web 的原生能力

每次添加框架依赖时,你都在押注该库的生命周期会超过你的项目。与此同时,Web 平台提供的功能是浏览器承诺永久支持的。框架提供的功能与原生浏览器 API 现在能处理的内容之间的差距已经显著缩小。

本文探讨了可以减少框架依赖的特定 Web 平台原生能力——以及如何使用 Baseline 作为指南来评估它们的就绪程度。

核心要点

  • Baseline 提供了一种可靠的方式来评估跨浏览器支持,当功能在所有主流浏览器中发布时会成为”新近可用”状态,在经过持续的跨浏览器支持期(大约 30 个月)后会成为”广泛可用”状态。
  • 原生浏览器 API(如 Popover API、View Transitions API 和 Navigation API)现在可以处理以前需要框架库的模式。
  • 现代 CSS 特性(包括 Anchor Positioning、Container Queries 和 :has())消除了许多 UI 场景中对 JavaScript 计算的需求。
  • 渐进增强架构让你在支持的情况下使用原生 API,同时为不支持的浏览器回退到框架解决方案。

理解 Baseline Web 特性

在采用任何原生浏览器 API 之前,你需要一种可靠的方式来评估跨浏览器支持。Baseline 正好提供了这一点。当一个特性在 Chrome、Edge、Firefox 和 Safari 的最新稳定版本中发布时,它就达到了”新近可用”状态。在这些浏览器中经过持续可用期(大约 30 个月)后,它就会成为”广泛可用”。

这对渐进增强决策很重要。Baseline 告诉你何时可以安全地将某个特性作为主要实现,以及何时应该将其作为回退增强体验。

你可以在 Web Platform Status 仪表板上验证任何 Web 特性的当前跨浏览器状态:https://webstatus.dev,该网站在一个地方跟踪 Baseline 分类和浏览器支持情况。

替代框架模式的原生浏览器 API

用于模态框和工具提示模式的 Popover API

React 开发者经常使用 Radix 或 Headless UI 等库来构建可访问的弹出框。Popover API 现在是 Baseline 新近可用的特性,可以原生处理这个问题:

<button popovertarget="menu">Open Menu</button>
<div id="menu" popover>
  <p>Menu content here</p>
</div>

浏览器管理焦点捕获、轻触关闭行为和顶层渲染。基本功能不需要 JavaScript。特性检测很简单:

if ('popover' in HTMLElement.prototype) {
  // Use native popover
} else {
  // Fall back to framework solution
}

用于页面动画的 View Transitions

单页应用程序的存在部分原因是多页导航感觉很生硬。View Transitions API 通过在 DOM 状态之间启用平滑过渡来改变这个等式:

document.startViewTransition(() => {
  updateDOMSomehow();
});

对于跨文档过渡,仅使用 CSS 就可以选择加入页面:

@view-transition {
  navigation: auto;
}

View Transitions 系列现在对于同文档过渡是 Baseline 新近可用的。不支持的浏览器会简单地跳过动画。

用于客户端路由的 Navigation API

像 React Router 这样的框架路由器存在是因为 History API 很笨拙。Navigation API 为拦截导航提供了更清晰的模型:

navigation.addEventListener('navigate', (event) => {
  event.intercept({
    handler() {
      return loadContent(event.destination.url);
    }
  });
});

Navigation API 现在是 Baseline 新近可用的,但这并不意味着你应该明天就撕掉你的路由器。这意味着你可以开始评估原生导航原语在哪些地方可以简化你的技术栈——特别是对于更轻量的”类应用”体验。

消除 JavaScript 的现代 CSS 特性

Anchor Positioning(锚点定位)

相对于触发元素定位工具提示和下拉菜单传统上需要 JavaScript 计算。CSS Anchor Positioning 以声明方式处理这个问题:

.trigger {
  anchor-name: --trigger;
}

.tooltip {
  position: absolute;
  position-anchor: --trigger;
  top: anchor(bottom);
  left: anchor(center);
}

这个特性还没有在所有主流浏览器中成为 Baseline 可用,所以严格将其作为渐进增强使用,在需要的地方提供 JavaScript 回退。

Container Queries 和 :has()

Container Queries 已经广泛可用,让组件响应其容器的大小而不是视口——消除了大量脆弱的 JS 布局逻辑。

:has() 选择器是新近可用的,解锁了以前强制使用基于 JS 的”父级感知”和状态反射的模式。因为它还没有广泛可用,根据你的受众,可能仍需谨慎——但现在它是一个可以通过适度回退来构建的真实选项。

用于 SSR Web Components 的 Declarative Shadow DOM

服务器端渲染 Web Components 以前需要复杂的水合操作。Declarative Shadow DOM 解决了这个问题:

<my-component>
  <template shadowrootmode="open">
    <style>/* scoped styles */</style>
    <slot></slot>
  </template>
</my-component>

shadow DOM 存在于初始 HTML 负载中——首次渲染不需要执行 JavaScript。这现在是新近可用的,可以在现代浏览器中使用,但特别是旧版本的 Safari 可能需要回退。

渐进增强作为架构

这里的模式不是”放弃框架”。而是认识到 Web 平台原语现在可以处理以前需要抽象层的特定问题。

特性检测支持这种方法:

  1. 检查原生 API 是否存在
  2. 在可用时使用它
  3. 在不可用时回退到框架解决方案

这遵循了长期以来的渐进增强原则,并为有能力的浏览器减少了包大小,同时在所有地方保持功能。

结论

根据当前的 Baseline 特性审查你的框架依赖。Popover API、View Transitions、现代 CSS 能力和 Declarative Shadow DOM 解决了仅在两年前就证明框架代码合理性的实际问题。

Web 平台发展缓慢但持久。达到 Baseline 状态的特性代表了稳定的基础。在这个基础上构建,只在平台真正不足的地方进行增强。

常见问题

通过检查相关对象上是否存在属性或方法来使用特性检测。例如,测试 'popover' in HTMLElement.prototype 来检测 Popover API,或测试 'startViewTransition' in document 来检测 View Transitions。如果检查失败,则回退到基于框架的解决方案。

新近可用意味着该特性在 Chrome、Edge、Firefox 和 Safari 的最新稳定版本中发布。广泛可用意味着它已经在所有主流浏览器中支持了一段持续时间(大约 30 个月)。广泛可用的特性在生产环境中使用时更安全,无需回退。

不一定。目标是减少不必要的依赖,而不是完全消除框架。在原生 API 完全解决你的问题时使用它们,但对于复杂的状态管理、路由逻辑或浏览器支持仍然有限的情况,保留框架解决方案。

对于跨文档过渡,添加 CSS 规则 @view-transition 并将 navigation 设置为 auto。浏览器会在页面加载之间自动处理动画。不需要 JavaScript,不支持的浏览器会正常加载页面,只是没有过渡效果。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay