如果没人写,Web Components 还有未来吗?
摘要
Nolan Lawson 探讨了在开发者采用率低迷的情况下 Web Components 是否还有未来。他指出,Google 的 Modern Web Guidance(现代 Web 指南)中几乎没有提到 Web Components,并认为与原生 HTML/CSS 特性相比,Web Components 对最终用户几乎没有带来额外收益。
<p><a href="https://lobste.rs/s/dpjkzz/do_web_components_have_future_if_nobody_is">评论</a></p>
查看缓存全文
缓存时间: 2026/10/20 02:07
# 如果没人再写 Web Components,它们还有未来吗?
原文来源:https://nolanlawson.com/2026/10/19/do-web-components-have-a-future-if-nobody-is-writing-them/
在我上一篇关于"拥抱平台原生能力"(https://nolanlawson.com/2026/10/03/why-dont-more-developers-use-the-platform/)的文章发布后,令我意外的是,[Hacker News](https://news.ycombinator.com/item?id=49950554) 和 [Lobsters](https://lobste.rs/s/srduzv/why_don_t_more_developers_use_platform) 上的讨论几乎都偏向了 Web Components。这让我感到惊讶,因为我在文章中根本没有提到 Web Components。不过,当我做了一些研究后就没那么意外了——"拥抱平台"这个口号最早是由 [Polymer](https://polymer-project.appspot.com/blog/2016-05-26-IO-2016-Recap) 推广开来的,那是 Google 早期基于 Web Components 的 JavaScript 框架尝试。2018 年他们甚至将其称为["我们的座右铭"](https://www.polymer-project.org/blog/2018-02-26-3.0-preview-paths-and-names)!这就解释了为什么很多人似乎把"拥抱平台 = 使用 Web Components"这个等式刻进了脑子里。
其实,我在文章中没有提到 Web Components 的原因之一是,在我看来,它们实际上并不是"拥抱平台"的好例子(无论这句口号的起源如何)。我转而使用了 HTML 和 CSS 功能的例子——它们通常性能更好、可访问性更强,且所需代码行数远少于用 JavaScript 实现的等效方案。这主要归功于浏览器厂商和标准组织(例如 [CSS 工作组](https://www.w3.org/groups/wg/css/) 和 [Open UI 项目](https://open-ui.org/))近年来取得的进步。
## 现代 Web 指南
不过,Web Components 又一次进入了我的脑海——因为 [Mastodon 上的一条评论](https://mamot.fr/@mokobien/117380327572292850)引导我看了 Google 的 [Modern Web Guidance](https://developer.chrome.com/docs/modern-web-guidance)(现代 Web 指南)。在写那篇文章之前我并不知道这个工具,但本质上它是一组技能(skills),你可以赋予 AI agent,引导它们更多地使用现代浏览器功能。本质上就是给 agent 的"拥抱平台"指南——至少是 Chrome 团队眼中版本的它。
然而,在观看[演示视频](https://youtu.be/bo3i0FzDUYo)时,我深感 Web Components 在整个图景中的位置难以辨认。在演示中,Phil Walton 展示了如何使用 Modern Web Guidance 创建一个更接近原生应用体验的 Web 应用,比如在触摸屏幕时平滑地跟随手指移动,这得益于 CSS [scroll snap points](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Scroll_snap)(滚动吸附点)和 [scroll-driven animations](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Scroll-driven_animations)(滚动驱动动画)等功能。但整个演示中我们几乎看不到任何实际代码——这完全是"凭感觉写代码"(vibe coding)。
观看时我一直在想,如果由我来构建 Modern Web Guidance,我会在哪里告诉 agent:"嘿,这里你应该使用自定义元素、Shadow DOM 或其他 Web Components 原语,因为这会让终端用户体验更好。"但我绞尽脑汁也想不出这样的地方。原因在于,Web Components **根本无法**真正改善终端用户体验。(当然,你可以说 Shadow DOM 提升了 CSS 性能,但我[已经做过大量基准测试](https://nolanlawson.com/2022/06/22/style-scoping-versus-shadow-dom-which-is-fastest/)了,而通过编译时 CSS 作用域隔离你可以获得同样的性能提升——Svelte、Vue 和 Tailwind 等许多框架和工具已经在这样做了。)
于是我查看了 Modern Web Guidance 的[实际代码](https://github.com/GoogleChrome/modern-web-guidance),我的直觉得到了证实:Web Components 感觉像是事后才补上的。在这个项目存在的头六个月里,几乎没有任何关于 Web Components 的提及。这直到三周前才有所改变——[一次提交](https://github.com/GoogleChrome/modern-web-guidance/commit/84ae7251ee919239d5ea85aef25897983f26601e)被合并进来,主要为那些*已经在使用* Web Components 的人提供了关于[可访问性](https://github.com/GoogleChrome/modern-web-guidance/blob/84ae7251ee919239d5ea85aef25897983f26601e/skills/modern-web-guidance/guides/html/accessible-web-components.md)、[预渲染](https://github.com/GoogleChrome/modern-web-guidance/blob/84ae7251ee919239d5ea85aef25897983f26601e/skills/modern-web-guidance/guides/html/prerendering-custom-elements.md)、[样式](https://github.com/GoogleChrome/modern-web-guidance/blob/84ae7251ee919239d5ea85aef25897983f26601e/skills/modern-web-guidance/guides/html/styling-web-components.md)等方面的指南。但 Modern Web Guidance 从头到尾都没有强烈建议 agent 使用 Web Components——事实上,其中有一整个章节标题为["决定你是否真的需要自定义元素"](https://github.com/GoogleChrome/modern-web-guidance/blob/b31dc0a43ff5d19bcf386a3476a216f3b39a6f55/skills/modern-web-guidance/guides/html/web-components.md#decide-whether-you-even-need-a-custom-element),读起来有时简直像是在劝退。
按照目前的写法,如果你把 Modern Web Guidance 提供给一个正在构建全新产品的 agent,我认为它不太可能选择使用 Web Components。
公平地说,有一个例外:[面向 Chrome 扩展开发者的一行建议](https://github.com/GoogleChrome/modern-web-guidance/blob/b31dc0a43ff5d19bcf386a3476a216f3b39a6f55/skills/chrome-extensions/references/extensions/content-scripts.md?plain=1#L102)推荐对注入页面的复杂 UI 使用 Shadow DOM。这在我看来完全合理,虽然这是一个相当窄的用例。[另一行](https://github.com/GoogleChrome/modern-web-guidance/blob/b31dc0a43ff5d19bcf386a3476a216f3b39a6f55/skills/modern-web-guidance/guides/html/web-components.md?plain=1#L3)建议在"设计系统、可嵌入的小部件和自包含 UI"中使用 Web Components,但这也相当狭窄,在我看来更像是在"决定你是否真的需要自定义元素"这一大背景下的一次轻描淡写的认可。
## Web Components 处于十字路口
那么,在这个新的 AI 编码世界中,Web Components 的位置在哪里?
我不打算重新阐述我对 Web Components 优缺点的所有观点;我已经在[相当](https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/)详[尽的篇幅](https://nolanlawson.com/2024/09/28/web-components-are-okay/)中讨论过了。我更想聊的是:当人们不再亲手编写代码(或者越来越多地连阅读代码都不再做)时,有什么新的变化?
这一节对我来说写得很痛苦,因为我花了多年时间参与基于 Web Components 的框架 [LWC](https://lwc.dev/) 的开发,参与 [Web Components 社区小组](https://www.w3.org/community/webcomponents/)和 [Accessibility Object Model 小组](https://github.com/WICG/aom),并且在[我的博客](https://nolanlawson.com/category/web-components/)上、在[播客](https://podrocket.logrocket.com/what-web-components-are-good-at)[中](https://shoptalkshow.com/451/)为 Web Components 辩护。然而我不得不承认,agentic coding(智能体驱动的编码)已经严重削弱了 Web Components 的核心价值主张。
简而言之,Web Components 的设计前提是:人们手工编写 HTML、代码是稀缺资源,因此复用是一种经济上的必然需求。而这些前提如今都不再成立了——至少不再那么成立,而且每天都在更加远离现实。因此,"遵循一个通用标准构建,你的组件就更容易被采纳和复用"这个电梯演讲,随着越来越多的人从零开始在一层几乎不可见的平台基座上"凭感觉"生成 UI,变得越来越缺乏吸引力了。
这不仅仅摧毁了 Web Components 的价值主张:它同样波及了那些启发了 Web Components 的 JavaScript 框架。我越来越频繁地读到团队[将整个前端从一个框架重写到另一个框架](https://dev.to/playfulprogramming/nobody-argued-for-your-stack-51fj)的报道,而其依据很大程度上只是"这对 agent 来说可能更好"这样的模糊感觉。不论这些重写是否合理(我认为它们应该更加以数据为依据,比如"它消耗的 token 更少"或"终端用户体验更快"),我们未来可能会看到更多这样的事情。而如果人们开始把框架层视为可丢弃的,那在他们眼中,框架层下面的那一层也不太可能有多大的价值。
正如我在[2023 年的一篇文章](https://nolanlawson.com/2023/12/30/shadow-dom-and-the-problem-of-encapsulation/)中所论证的那样,组件库早已从"开箱即用"的模式转向了更偏向"自己动手"(DIY)的思路。而 [shadcn/ui](https://ui.shadcn.com/) 就是这种趋势的极致体现——它看起来像是一个吐出成堆样板代码的机器,但在某种意义上,这正是它的目的所在。与其让你与组件系统的接触点变成一个僵化的、抗拒你去定制和调整的 API,你不如直接把各个零件导入进来,然后随心所欲地重新组合。这种转变在 AI 编码出现之前就已经开始了,而现在有了 LLM,"成堆的样板代码"反而成了一种优势而非负担。
而这一切都没有发挥 Shadow DOM、反射属性(reflected attributes)或其他 Web Components 核心特性的优势。
## 拯救 Web Components
在这个 AI 编码的新世界中,我可以尝试为 Web Components 提出两个(略微站不住脚的)论点。
第一个是所谓的"微前端"——即将大型 UI 分割成多个部分,由不同团队独立构建而不互相干扰。Web Components 明确是为这种场景设计的:避免["友军误伤"](https://bkardell.com/blog/FriendlyFire.html)(用 Brian Kardell 的精辟说法)。在 agent 世界中,这种沙箱隔离其实是一种众所周知的技术——通常你希望将 agent 隔离在严格的边界内,避免它们互相践踏。换句话说,Web Components 理论上可以让你拥有多个 agent 群体同时工作在 UI 的不同部分,而它们的 CSS、事件或全局变量不会相互冲突。
明显的反驳是,Web 平台已经拥有了出色的沙箱原语:iframe。iframe 提供了比 Web Components 更牢固的边界——不仅组件之间相互隔离,而且它们运行在不同的 JavaScript realm 中,`postMessage` 是唯一的通信通道。这里有一些我不打算展开讨论的权衡(同步与异步通信、内存使用、closed 与 open shadow DOM 的隔离程度差异),但我确实认为 Web Components 在这场竞争中还有机会。(可以说,Modern Web Guidance 中提到的"设计系统和自包含 UI"也是类似微前端的场景,在这些场景中 Web Components 可以大放异彩。)
第二个论点是,即使重写只需要一个 prompt 的距离,复用仍然重要。例如,我仍然相信我的 `<emoji-picker>` 元素(https://github.com/nolanlawson/emoji-picker-element/)是一个高效 Web Components 的优秀范例:没有必要在 React、Vue、Svelte 和其他十几个框架中分别重建这个东西,尽管如今用 LLM 可以轻松做到。它是一个独立的、纯客户端组件,其大部分复杂性在于管理 emoji 数据、IndexedDB 等,几乎不需要与框架有任何交互点来管理渲染或生命周期。因此,将其打包为 Web Component 并允许开发者用他们选择的框架(或者不用框架)来包装它,仍然是一个合理的分发模式。
反对将 Web Components 作为复用的[通用语](https://en.wikipedia.org/wiki/Lingua_franca)(lingua franca),在我看来就像在说在 agentic 时代所有代码共享甚至开源本身都是浪费时间。我的同事 André Staltz 已经证明[这显然是错误的](https://socket.dev/blog/ai-has-taken-over-open-source):如果有什么变化的话,AI 编码正在增加共享代码的数量,而不是减少。即使你*能*用 agent 重建某个东西,也不意味着值得为此花费 token。(尽管我仍然对[较小的开源项目](https://nolanlawson.com/2025/11/16/the-fate-of-small-open-source/)的命运感到担忧。)
更有力的反驳是:agent 已经拥有了一个完全够用的组件复用层,那就是 [React](https://youtu.be/P1FLEnKZTAE)。但我不这么认为,因为我不相信 React 是世界上最后一个我们需要的 JavaScript 框架。像 [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark) 和 [isomorphic SSR benchmark](https://github.com/marko-js/isomorphic-ui-benchmarks) 这样的性能基准测试仍然顽固地反驳着 React 的采用:事实证明,[虚拟 DOM 就是纯粹的开销](https://svelte.dev/blog/virtual-dom-is-pure-overhead)。React 当然可以为 agentic 时代重塑自己,但我猜这可能会导致兼容性问题,从而更有理由采用 Web Components——至少可以摆脱无休止的更新负担。
不过,我认为所有论点中最强的一个是:无论是 Web Components、React 还是任何其他框架,其实都无关紧要——最多不过是某个人的 `AGENTS.md` 文件中的一个脚注,或者 agent 思考过程中的一句旁白。最近我为妻子凭感觉写了一个小应用,agent 提到它在 Preact 和 Svelte 之间犹豫不决,最终选择了 Preact。说实话,我完全不在意,因为应用能用,解决了眼前的问题。
## 结论
我仍然对 Web Components 有深厚的感情,如果需要的话,我会欣然为它们辩护,反驳任何批评者。甚至这个网站上就有一个 Web Components!上方的主题选择器就是一个 ["HTML web component"](https://adactio.com/journal/20618)(或称"light DOM 组件"),我觉得它是对老式"jQuery 点缀式 HTML"方法的一个相当不错的替代方案。在 `connectedCallback` 中定义初始化逻辑,比起笨拙的 `querySelector` 杂技,*感觉*上更干净。
话虽如此,我得承认我是明确告诉 agent 使用 Web Component 的(否则我敢肯定它会耸耸肩,直接用 `querySelector` 搞定)。
尽管我对 Web Components 有感情,但我认为那些从事标准制定、框架开发或浏览器实现的 Web Components 倡导者们必须加倍努力,才能论证它们在 AI 编码未来中的相关性。我已经不再参与这场争论,但我查看了一些 Web Components 长期存在的问题的状态,失望地发现[服务端渲染](https://github.com/whatwg/html/issues/10673)、[样式表共享](https://github.com/WICG/webcomponents/issues/909)和[可访问性](https://chromestatus.com/feature/5188237101891584)似乎仍未解决。这些缺陷——请注意,它们直接影响终端用户体验,因此不因 AI 编码而改变——必须被修复,Web Components 才有一线生机。
如果 Web Components 无法存活,或者它们逐渐衰败为[少数网站](https://chromestatus.com/metrics/feature/timeline/popularity/1689)中被遗忘的基础设施,那它们留下了什么成就呢?
嗯,我确实认为 Web Components 有一个明确的胜利成果,那就是"解释平台"。这是 [Web Components 最初的目标之一](https://domenic.me/explaining-away-the-webs-magic/):拿一个原生 HTML 元素,比如 `<video>` 或 `<input type="range">`,然后解释 Web 开发者如何从平台原语构建出同样的东西。事实上,如果你查看浏览器的 DevTools,你甚至能在这些元素内部看到隐藏的"用户代理 Shadow DOM"(user-agent shadow DOM)。
(一个 Chromium DevTools 的示例截图,展示了一个带控制条的 `<video>` 元素的用户代理 shadow root。视频显示在左侧,右侧是 DevTools 的 Elements 面板……)
相似文章
为什么更多的开发者不“使用平台”?
Nolan Lawson 的博文探讨了为什么 Web 开发者常常避免“使用平台”——比起原生浏览器 API 更倾向于使用第三方库——并分析了浏览器历史碎片化、React/npm 生态的熟悉度以及文档质量这三大关键因素。
渐进式 Web Components
Ariel Salminen 介绍了 Elena,一个 2.6kB 的开源库,用于构建渐进式 Web Components,这些组件无需 JavaScript 即可渲染 HTML 和 CSS,并逐步增强。文章解释了该方法背后的设计理念和分类法。
框架还重要吗?
一篇讨论在当前环境下 Web 开发框架是否仍然重要的博客文章。这是一篇简短的文章公告,现已迁移到新地址。
AI网页应用构建器在2026年还值得使用吗,还是说热炒的基本都是原型魔法?
反思性分析:像Lovable、Bolt.new和Replit Agent这样的AI网页应用构建器在2026年是否仍然值得使用,探讨它们在原型阶段之外,对于严肃的生产级应用是否依然可靠。
可持续的 Web 职业生涯,以备这场风暴过去之后
设计师兼前端开发者 David Bushell 认为,Web 从业者应当以深耕持久技能——无障碍访问、深入的 CSS 知识和沟通能力——来应对行业由 AI 驱动的低迷期,而非盲目追逐热点。