【CSDN 编者按】该文章主要探讨了 Web 组件的优缺点以及适用场景。作者认为 Web 组件在 DOM 树叶子节点、设计系统和企业级应用中表现出色,但也指出了其在服务器端渲染和可访问性方面的不足。文章强调,Web 组件不是一种全能的解决方案,而是应在其擅长的领域中得以应用。
原文链接:https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/
未经允许,禁止转载!
作者 | Nolan Lawson 译者 | 明明如月
责编 | 夏萌
出品 | CSDN(ID:CSDNnews)
近期,Dave Rupert 的文章《 Web 组件究竟有何优势,我为何未采用?》引发了广泛讨论。作为一个拥有多年 Web 组件使用经验的开发者,我想分享一下自己的看法。
在分析问题之前,我想先给出一个典型的“资深工程师”的看法:是否应该使用 Web 组件取决于具体场景的需要。现在,让我们首先探究 Web 组件在哪些场景表现更出色,然后再分析其存在的局限性。
在我看来,Web 组件特别适用于 DOM 树中的叶子节点,也就是那些不需要服务器端渲染(SSR)和没有内嵌内容的组件。具体而言,如富文本编辑器、日历插件和颜色选择器等。
在此场景中,一些常见于 Web 组件的挑战,如服务器端渲染(SSR)、hydration、插槽(slotting),或甚至是 Shadow DOM,都不再是问题。如果你不使用框架,或者使用一个支持 Web 组件的框架,你只需要把
以我的 emoji-picker-element 组件为例,仅需一行 HTML 代码即可导入:
用法也非常简洁:
emoji-picker-element 组件效果截图
这样,无需依赖打包工具、转译器或特定框架,简单复制粘贴即可。这不仅适用于小型项目,也已成功应用在复杂的单页应用(SPA)中,这也体现了 Web 组件的广泛适用性。
这完全符合 Web 组件的设计初衷:使自定义 Web 组件的使用与内置 HTML 元素一样简单。
设想这样一个场景:你手头有一个庞大的 React 项目,它已经稳定运行了相当长的时间。现在,团队计划转向 Svelte。这是否意味着你必须从头到尾重构代码库,并且还需要为每一个第三方组件找到其 Svelte 版本?
前端开发者在考虑从一个框架迁移到另一个框架时,通常会担心巨大的迁移成本。然而,最大的误区则是将 Web 组件也看作是与此相似的问题。
实际上,Web 组件的核心价值在于解决这种框架依赖性带来的问题。如果你打算从 Vue 切换到 Lit,或从 Angular 切换到 Stencil,而且还计划一次性重构所有组件,那么你无疑是在给自己制造麻烦。
更合理的做法是允许新旧代码并存,并用 Web 组件作为中间层,实现两者的无缝对接。这样,你就无需一次性全面重构代码:
Web 组件能够进行属性(props)传递和事件(events)触发,这基本上覆盖了它们的核心功能。如果你使用的框架支持 Web 组件,这一切都是开箱即用的。即使不支持,你也可以通过编写轻量级的适配代码来实现。
虽然有人可能对一个页面上混用多个框架有所保留,但这种担忧更多地是基于直觉而非实证数据。如果你使用的是元框架进行服务器端渲染(SSR)和客户端数据注入(hydration),那么部分迁移的操作可能比预期更为复杂。但 Web 组件的一大优势就是能在客户端明确规定如何将两个组件组合在一起。
因此,如果你和你的团队不想再频繁进行全面的代码重构,那么使用 Web 组件可能是一个好的选择。
如果观看了 Cassondra Robert 在 CSS Day 上的精彩讲解,你会发现一个展示了多个知名企业的 Logo 的页面,这些都是 Web 组件广泛使用的佐证。
如果这还不够的话,你还可以参考 Oracle、SAP、ServiceNow 等其他众多企业。
你可能没有意识到,在多数大型企业(例如,我所就职的公司)中,Web 组件已经在其设计系统和组件库中得到了广泛应用。尤其是对于那些常在 Web 开发社区中活动的人来说,这样的现象可能颇为令人惊讶。更令人震惊的是,根据某些统计数据,尽管 React 在网页中的使用率约为 8%,Web 组件的使用率却高达 20%。
实际上,许多大企业往往并不在社交媒体平台如 Twitter、Reddit 等上积极推广 Web 组件或者提供相关教程。与此相对的是,社交媒体上却有大量技术达人在紧密跟踪 React 的每个小版本更新和其生态系统的新动态。这一现象的背后逻辑相当直接:大企业通常更注重内部沟通,而在公开场合相对低调;反观中小企业和自由职业者,他们则相对更活跃于社交媒体。因此,如果 Web 组件在企业内部获得了更高的接受度,单凭频繁浏览 Twitter 是难以察觉的。
那么,大型企业为何如此偏爱 Web 组件呢?首先,基于 Web 组件构建的设计系统具有跨环境的可运行性。在一个大型企业中,前端技术栈可能包括 React、Angular、Ember 以及静态 HTML,而这些都需要与企业的主题和品牌保持一致性。对于初创企业而言,进行大规模的代码重构或许是一种有益的尝试,但在企业层面,这样做并不现实。
因为企业通常维护着庞大的代码库,并且需要在更长的时间尺度上进行规划,这促使了其做出与众不同的技术决策。从我的观点来看,这正是企业更倾向于使用 Web 组件的根本原因:稳定性和可持续性。
考虑到常规的 React 代码库,你可能发现更新任何依赖项(例如 React Router、Redux 或 React 本身)会触发一系列破坏性变更,这要求你花费数周时间对代码进行重构。在这种环境下,即使一个细微的变更也可能激活 Hyrum 法则,影响数千个组件,甚至简单的小版本升级也需要数周的全面测试、验证和文档更新。在这个场景中,React 的小版本升级相当于一个复杂问题,而大版本升级则可能引发一场危机。
Hyrum 法则:如果一个 API 的实现细节发生了变化,可能会导致一些用户的程序出现问题,因为他们已经习惯了之前的行为。因此,API 的设计者和维护者需要考虑到用户的期望和依赖,尽量保持 API 的稳定性和兼容性。
相反,Web 平台的向后兼容性为稳定性提供了保障。举例来说,1996 年发布的 Space Jam 网站至今依然可运行。Web 组件强化了这种稳定性,对于那些不能频繁进行前端重写的企业来说,这是一个重要优势。
当你采用 Web 组件后,其功能和特性保持稳定,包括 Shadow DOM 的样式隔离等它所有的微妙之处也都是如此。你可以将代码逻辑委托给浏览器来执行,从而长期减少维护和验证的需求。事实上,这样做就相当于把维护的责任交给了 Google、Apple 和 Mozilla 等浏览器厂商。
与 Web 平台的稳定性相符,企业通常也更加稳定、谨慎,并且注重规避风险。因此,可以理解为什么Web组件在企业界得到了如此广泛的应用和欢迎。
在讨论 Web 组件的优势的同时,我们也需要深入了解其不足。以下是 Web 组件的几个主要局限性:
服务端渲染(SSR):当前在 Web 组件领域,服务端渲染仍然是一个悬而未决的问题。尽管存在如 Shadow DOM 这样的声明式解决方案,但这只解决了问题的一部分。至今尚无统一标准明确如何在服务器端渲染 Web 组件,导致各大框架在这方面的实践各异。例如,Lit SSR 尚处于“Lit 实验”的研发阶段。只有当未来服务器端能渲染多种 Web 组件框架,且确保这些框架能顺利集成和重新渲染,我才会认为这个问题解决了。然而,解决这个问题可能还需要数年的时间。
可访问性:在主文档中的 ARIA 属性可能无法轻易地引用或与 Shadow DOM 内部的元素进行交互,并且处理对话框和焦点也颇具复杂性。因此,如果你希望不损害可访问性,必须从设计之初就仔细规划你的组件结构。尽管有许多正在进行的工作试图解决这个问题,但必须承认,到了 2023 年,这方面仍面临很多挑战。
此外,还有其他一些问题,例如依赖问题(如依赖特定的框架、构建工具和测试运行器)、IE11 的遗留问题(这是一些开发者极力避免但无法摆脱的问题)以及开发者的平台疲劳(例如,“我已经熟练掌握了 React,不想再去学习其他新技术”)。对于这些问题,我能理解并非每个人都会觉得 Web 组件有吸引力。Web 是一个包罗万象的平台,各种应用和用途都能在此找到自己的位置,这也是它之所以令人赞叹的一方面。
不论你是选择立即采用 Web 组件,还是选择观望,或是打算几年后再重新评估,届时网络标准和功能可能会更加完善。
我个人对 Web 组件持积极态度,但也明白这并非人人共识。我的目的并不是要过分强调其重要性,只是认为它是开发者工具集中的一个有用组成部分。关键在于如何最大化其优势,同时规避潜在不足。
Web 组件和网络标准让一些细微的问题可以由浏览器自行处理,这点我非常喜欢。组件如何组合、样式作用域如何限定、数据如何传递——这些问题可以放心交由浏览器解决。这让我能够更专注于对终端用户确实重要的因素,如性能、可访问性和安全性。
在网络开发领域,我常感到自己在与与业务目标无关的“附加复杂性”做斗争。这可能包括管理 npm 依赖、调试状态管理器,或者解决测试运行器和代码检查工具的兼容性问题。虽然有人可能觉得这些问题有趣,我也不时会陷其中,但这些最终只是低效的劳动,因为你的最终用户并不在乎你的打包器是否与你的 TypeScript 转译器兼容。
换句话说,在 2023 年,选择 Web 组件会带来一些附加的复杂性,如前面提到的 SSR 和可访问性问题。在这些方面妥协可能会对你的最终用户造成实际上对他们很重要的伤害,所以这种权衡可能不值得你做。我认为这种权衡通常是值得的,但同时也存在一些微妙的差异。“专用 Web 组件来发挥其优点”虽然听起来不太吸引人,但在 2023 年,这仍是一个不错的选择。
参考链接
《Web 组件究竟有何优势,我为何未采用?》:https://daverupert.com/2023/07/why-not-webcomponents/
emoji-picker-element:https://github.com/nolanlawson/emoji-picker-element/
复杂的单页应用(SPA):https://www.npmjs.com/package/emoji-picker-element?activeTab=dependents
支持 Web 组件:https://custom-elements-everywhere.com/
轻量级的适配代码:https://github.com/rstacruz/remount
更多地是基于直觉而非实证数据:https://nolanlawson.com/2021/08/01/why-its-okay-for-web-components-to-use-frameworks/
Cassondra Robert 在 CSS Day 上的精彩讲解:https://www.youtube.com/watch?v=67bSCEEdaH8
根据某些统计数据:https://mastodon.social/@westbrook/110774427407999573
网页中的使用率约为 8%:https://almanac.httparchive.org/en/2022/javascript
20%:https://chromestatus.com/metrics/feature/timeline/popularity/1689
Hyrum 法则:https://www.hyrumslaw.com/
1996 年发布的 Space Jam 网站:https://www.spacejam.com/1996/
它所有的微妙之处:https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/
尚无统一标准:https://github.com/webcomponents-cg/community-protocols/issues/7
Lit SSR:https://lit.dev/docs/ssr/overview/
“Lit 实验”:https://lit.dev/docs/libraries/labs/
在主文档中的 ARIA 属性可能无法轻易地引用或与 Shadow DOM 内部的元素进行交互:https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/
对话框:https://nolanlawson.com/2022/06/14/dialogs-and-shadow-dom-can-we-make-it-accessible/
焦点:https://nolanlawson.com/2021/02/13/managing-focus-in-the-shadow-dom/
正在进行的工作:https://github.com/WICG/aom/pull/200
解决这个问题:https://github.com/WICG/aom/issues/199
推荐阅读:
▶9月7日,与CSDN CEO 蒋涛一起迎接智变加速时刻
▶游戏开发调用 ChatGPT API,独立开发者哭诉:应用被下架,多年的存款和心血没了
▶编程世界的革新之道:Code Llama