web技术发展的现状
自2020年v1完全支持以来,Web Components的世界发生了更多的变化。
让我们看一下使用当前标准构建的值得注意的示例,以及将于2023年和以后推出的新Web Components标准工作。
原文链接: https://eisenberg effect.medium.com/2023-state-of-we B- components-c8 feb 21 d4f 16
原文: 3359 blog.5 bang.top/2023/04/21/2023 _ state _ of _ web _ component
未经许可禁止转载!
作者| @EisenbergEffect翻訳者| @5bang編集|夏萌出品| CSDN
Web Components 应用实例
随着所有浏览器都支持 v1 Web Components,许多公司已经采用并基于这些新标准构建了重要的业务。
以下是我认为值得注意的例子。
YouTube
YouTube 是最早采用 Web Components 技术的应用之一,多年来一直使用这种技术构建其界面。
检查源代码时,您将看到从ytd-video-preview到iron-ally-announcer的各种定制元素。
Photoshop
是的,Adobe 使用 Lit 将 Photoshop 带到了浏览器中。
现在还是测试版,如果你是adobe的订阅用户,可以自己尝试。
整个APP应用程序具有许多定制元素,从构成APP应用程序根的psw-app,到像psw-layers-panel这样的shell元素,再到像sp-action-button这样的UI组件。
MSN, Edge, Bing, VS Code, and More at Microsoft
几年前,微软使用基于 FAST 的 Web Components 重构了 MSN。
这样可以将性能提高30%到50%,比以前使用React构建的版本更好。
基于 OpenAI 的 New Bing 也是使用 FAST Web Components 构建的,如下面的屏幕截图所示,最近由其中一位开发人员分享。
甚至用于扩展 VS Code 新功能的 Webview UI 工具包,也是使用 FAST Web Components 构建的。
在过去三年中,微软大约有 1,500 个团队/项目采用了 FAST Web Components。
Salesforce
作为客户关系管理、销售和营销自动化平台行业中最大的品牌之一,Salesforce 多年来一直在基于 Lightning Web Components 进行开发。
SpaceX
如今,Web Components 甚至在太空中也得到了应用。
SpaceX的船员显示屏运行着Chromium,Web Components被广泛使用。
標準
Web 标准不断发展,其中包括 Web Components。
在v1版本向所有主要浏览器发布的三年间,Web Components的功能数量几乎翻了一倍。
以下是正在发布、正在进行和计划的各种Web Components相关标准的图示。
让我们逐一查看图示中按照功能划分的六个高级类别中的每一项:组合和作用域、平台互操作性、渲染和性能、样式、包和分发、API 范式。
组合和作用域
Web 组件的作用域/封装特性对于传统编程中的信息隐藏、维护、代码库可扩展性等方面同样非常重要。
但是,如果包含Web Components,请在HTML和CSS运行时提供其他元数据以优化呈现和布局。
Shadow DOM
hadow DOM 是 HTML 中用于作用域、封装和组合 DOM 及相关样式的基本机制。
它是多方面的特性,具有很多不断扩张的能力。
命名插槽分配—— 原始的 v1 Shadow DOM 规范提供了一种完全声明式的机制,用于在 Shadow DOM 中使用命名的 slot元素来定义元素组合的占位符。
只要开发人员将slot属性放置在主体元素的任何子元素上,浏览器就会自动将该元素的渲染输出“插入”到插槽位置。
开放和封闭模式—— v1 Shadow DOM 规范中的 attachShadow() API 的 mode 选项是其中一部分。
允许组件开发人员选择首选的包模式。
在open模式下,可以从主体元素外部访问shadowRoot,但在closed模式下无法访问。
事件重新定向—— 当在 Shadow DOM 内部的元素上触发事件时,这些事件会被『重新定向』,以便它们看起来来自宿主 Shadow DOM。
v1 Shadow DOM规范的能力是正确封装内部结构的重要部分。
手动插槽分配—— slot 元素上的新的 assign API 扩展了 v1 的原始插槽分配功能,除了之前的声明性式插槽机制外,还提供了一种命令式 API。
焦点委托—— 这个在 v1 之后的特性使 Shadow DOM 可以告诉浏览器,当其宿主元素获得焦点时,它应该将焦点委托给 Shadow DOM 中的特定元素。
默认情况下,会选择第一个可聚焦的元素,但可以使用autofocus属性复盖此行为。
Cross-root ARIA—— 即将到来的特性,与社区和浏览器厂商接近达成共识,Cross-root ARIA 将极大简化在 Shadow DOM 外部与 Shadow DOM 内部的 ARIA 关键元素相关联的操作。
例如,将Shadow DOM外部的label元素与Shadow DOM内部的输入元素相关联。
这些类型的ARIA场景今天已经有解决方案,但不容易实现。
Cross-root ARIA将会大幅改善这种状况。
在 Shadow CSS 中使用自定义属性—— 如今,一些浏览器可以使用 @property 语法来自定义 CSS 属性。
但是,目前在Shadow DOM中还没有发挥作用。
在CSS对象模型中,这些属性始终可以通过自定义元素代码全局定义,但在常识上,以Shadow DOM声明的形式提供此功能已有所改进。
这已经达成共识,我们希望很快能看到这个功能。
浏览器现在更常见地支持新的CSS语法。
作用域元素注册表
自定义元素的 v1 规范中,所有元素都通过 customElements 全局对象在全局自定义元素注册表中注册。
此新的补充功能允许您实例化非全局注册表并在其中注册定制元素。
const myRegistry=new CustomElementRegistry(); myRegistry.define(‘my-element’, MyElement);这个注册表中的元素仅定义为该注册表所分配的 Shadow DOM。
这大大改进了浏览器的作用域,使您可以根据需要定义每个shadow root的元素。
应用于浏览器后,这将是一大进步,并为新体系结构的可能性打开大门。
现在社区和制造商之间达成了共识,Chromium正在开发第一个实施。
平台互操作性
Web Components 最重要的方面之一是它们如何在组件和平台之间实现互操作性。
看看现在和未来的特性吧。
自定义元素
自治自定义元素—— Web Components v1 的这个核心功能通过向 customElements 全局对象注册一个类来定义继承自 HTMLElement 的自定义元素。
基本的生命周期回调和观察属性也是规范的一部分。
自定义内置元素—— 最初,有一个提案允许从内置元素继承,但 WebKit 实现者发现了几个技术问题,因此已经拒绝了这个规范。
因为将来被删除的可能性很高,所以应该避免使用。
有关更好的替代方案,请参考下面的“自定义属性”。
Element Internals
一个 v1 之后的新 API,ElementInternals,使得自定义元素能够更深入地与现有的 DOM 子系统进行平台级集成。
Shadow Root 访问 —— 这个简单的功能添加使组件开发者可以检索一个 closed 模式元素的 Shadow Root 实例。
如果没有此功能,则具有closed架构声明的Shadow DOM元素在运行时将无法访问根节点。
与表单关联的自定义元素 —— 这个重要的新功能使得自定义元素能够完全参与表单,包括表单验证、提交和重置。
默认可访问性角色、状态和属性 —— 这个新的 API 集合 使得可以通过直接在内部与平台进行通信来设置自定义元素的默认可访问性特性,而不是通过可能被用户无意中删除的宿主元素上的外部属性。
目前,除Firefox外的所有主要浏览器都支持此新的API,并且Firefox提供了polyfill。
Firefox已经实现了ElementInternals其他部分的API,所以如果他们在不久的将来没有发布这个功能,你会感到惊讶。
组合选择
这个改进提出了一个新的 getComposedRange() API,用于 Selection 对象,它使得范围的起始和结束可以跨越多个 Shadow Root。
它还将提高浏览器在处理这些情况时的一致性。
对该API草案有普遍共识,但在浏览器实现之前,需要完整的规范。
在Web Component的正常开发过程中,很少可能会遇到这种情况。
主要与富格文本编辑器的实现有关。
自定义属性
虽然这个功能不一定是 Web Components 的一部分,但它与 Web Components 旨在服务的场景有很高的重叠。
该草案建议根据类似Web Components的架构,启用可附加到任何HTML元素的可复用行为的创建。
例如,想象一下,您想将Material Design水印效果应用于任何HTML元素。 那样做不就好了吗?
这个功能的编程模型可能是什么样的? classmaterialrippleextendsattr//ownerelementinheritedfromattr//nameinheritedfromattr/valueinheritedfromatttr//.coneconelelematid calledwhentheownerelementisconnectedtothedom//orwhentheattributeisaddedtoanalreadyconnectedowner ) disconnected calllback ( calledwhentheownerelementisdisconnectedfromthedom//orwhentheattributeisremovedfromaconnectedowner } attributechangedcalllbacom calledwhenthevaluepropertyofthisattributechanges } } custom attributes.define ( ' material-ripple 'MaterialRipple ); 你可能注意到了,
这也将为被拒绝的可定制内置自定义元素提案中的is 属性提供更好、更健壮的替代方案。
渲染和性能
渲染和性能对于 Web Components 来说非常关键。
虽然基本功能已经就位,但这仍然是一个活跃的探索、讨论和未来创新的领域。
HTML Template 元素
HTMLTemplateElement及其定义惰性 HTML 内容的能力是 v1 Web 组件功能的关键部分。
在引入该元素之前,没有办法声明不会被浏览器激活的HTML,因此很难创建需要在需求时重复渲染相同HTML 的组件。
声明式 Shadow DOM
Shadow DOM 的 v1 规范仅允许通过 attachShadow() JavaScript API 创建 Shadow Root。
这个Shadow DOM 的新增增强功能允许在HTML 中完全声明Shadow DOM 内容,无需使用JavaScript,为服务器框架提供了有趣的可能性。
host-element template shadowrootmode=’open’ slot/slot /template h2Light content/h2 /host-element这个规范重用了 template 元素。
不要被这个搞混了。
它不是一个模板,它是由HTML 解析器流入Shadow Root 的活动DOM。
当前除了 Firefox 之外,所有浏览器都支持声明式 Shadow DOM。
如果需要,该功能可以通过几行JavaScript 代码进行polyfill。
子节点更改回调函数
Web Components 在自定义元素的 v1 规范中有一个明确定义的生命周期,但这并不意味着我们不能在未来扩展这个生命周期。
其中一个常见的对于开发者的挑战是使Web Component 能够对子节点的添加或删除做出响应。
虽然现在可以使用slotchange事件和MutationObserver 实现这一点,但是如果有一个像childrenChangedCallback() 这样的生命周期回调函数,
可以提供更好的性能、简化和与HTML 解析器本身的集成,那就更好了。
目前有一个草案提议,并且实现者也表现出了兴趣。
需要一份完整的提案来推动这个功能进入下一个阶段。
模板实例化
虽然 HTML 有模板,但它还没有一种机制来实例化与数据连接的模板,并在其相关数据更改时更新它们。
这个『模板实例化』的领域有几个独立有价值的部分。
DOM 部件 – 这个提案 将提供一种标准机制,在 DOM 树的特定位置插入或替换内容。
你可以把它看作是一种低级别的启用器,帮助创建更高效的模板引擎和批量更新现有的Web Component 库和JavaScript 框架。
它不提供响应性解决方案或模板语法,只提供定位和更新DOM 部分的低级别标准基础设施。
模板语法 – 一旦定位和批量更新的低级别基础设施就位并被现有库成功使用,那么关于语法的大辩论就会开始。
模板语法是一个非常有争议的问题,但我们已经认识到HTML 应该有一个基本的语言来处理这个问题,即使它只是为其他库提供编译目标。
响应性 – DOM 部件提供批量更新 DOM 的标准机制。
模板语法提供声明式机制来创建DOM 部分。
剩下的是确定何时应执行DOM 部件更新的机制。
这就是响应性的作用,以完成整个图景。
这是另一个有争议的问题,但已经有一些先例,例如通过Web Components 的attributeChangedCallback()。
这个主题需要更多的探索。
模板实例化工作类别被分解为上述三个子特性,旨在先解决某些较少有争议的问题,并为现有库和框架提供路径,以利用不那么主观的、改进性能的功能,避免在社区中引起过多争议。
样式
虽然 Shadow DOM 提供了样式的封装,但有许多 CSS 特性直接与 Web Components 相关,并且在日常使用中非常重要。
使用
几项当前和未来的标准与 Web Components 如何使用样式来创建 Shadow DOM 的呈现方式有关。
虽然一直以来都可以在Shadow DOM 中创建样式元素,但新标准提供了更好的可读性和性能优势。
可构建样式表 — 你知道在这个标准之前实际上无法创建 CSSStyleSheet 实例吗?这个标准修复了这个问题,现在您可以编写代码 new CSSStyleSheet()。
这种能力使得在Web Components 中更动态地创建和使用样式成为可能,包括在组件之间共享样式表。
采用样式表 — 针对给定的 CSSStyleSheet 实例,如何将其与特定的 Shadow Root 或全局 document 关联起来?这个新标准 在 document 和所有 Shadow Root 实例中添加了一个 adoptedStyleSheets 数组。
只需将样式表推入该数组中,就可以开始使用了。
CSS 模块脚本 — 可构建样式表和采用样式表本身提供了创建、共享和关联文档表的原始机制,但仍需要在 JavaScript 中编写 CSS 代码。
CSS 模块脚本标准允许使用JavaScript 模块导入.css 文件,从而平台会自动创建一个CSSStyleSheet 实例,
无需在CSS 运行时和JavaScript 运行时之间来回切换。
声明式 CSS 模块 — 随着声明式 Shadow DOM 和采用样式表的出现,已经创建了几个临时提议,以便声明 CSS 模块并将其与声明式 Shadow DOM 关联。
这方面需要更多的探索,但这是HTML 和CSS 未来的一个令人兴奋的可能性。
呈现
主要来说,CSS 关注的是呈现方面的问题。
有一些标准扩展了Web Components 的样式设置的可能性。
不仅仅是 Web Components,对于创建组件系统来说,自定义 CSS 属性 是一个非常重要的规范,它能够创建本地 CSS 变量,并可以在 shadow roots 中使用。
CSS Shadow Parts — CSS 部分 允许在 Shadow DOM 中声明元素作为『部分』,可以使用外部选择器对其进行样式设置。
这是通过part 属性和the exportparts 属性实现的,用于嵌套场景。
CSS 自定义状态 — 原生元素可以具有自定义状态,在 CSS 选择器中可用。
例如,复选框的『已选中』和『未选中』状态。
这个新功能允许Web Components 定义自己的状态。
已经达成共识,Chromium 已经发布了第一个实现,可以通过ElementInternals 访问。
在等待其他浏览器跟进时,可以使用polyfill 进行支持。
CSS 主题 — 尽管可以通过仔细使用 CSS 自定义属性和 CSS Shadow Parts 来实现丰富的主题化,但可以通过明确地将主题的概念引入 CSS来简化和改进这一过程。
开放式 Shadow Root 样式 — 尽管可以使用可构建样式表和采用样式表使任何全局 CSS 在 Shadow Root 中共享,但对于普通 Web 开发人员来说,这可能不是一个直观的过程。
有一些探索机制的方法,明确选择允许外部CSS 进入某些shadow roots。
打包和分发
到目前为止,我们主要谈论了与 Web Components 实现相关的标准。
但同样重要的是考虑组件如何打包和加载。
自定义元素懒加载
现在,我们可以使用全局的 customElements 注册表定义组件,很快还可以使用自定义注册表。
但是,在这两种情况下,在定义组件之前,组件的实现必须已经被加载。
使用自定义元素懒加载,开发人员将能够告诉平台有关元素的信息,但是可以延迟加载它,直到元素首次出现在document 中时才加载。
它可能会像这样工作:
customElements.defineLazy( ‘my-element’, async ()=\ (await import(‘my-element.js’)).default );这个规范似乎被大多数人认为是一种很好的东西,尤其是对于某些架构来说。
然而,该提议的细节仍在争论中。
HTML 模块脚本
HTML 模块脚本是 CSS 模块脚本的 HTML 等效物。
通过HTML 模块脚本提案,模板将通过JS 模块系统直接可导入。
目前只有一个草案提案,还需要进一步讨论许多细节,但这被认为是一个重要的长期增强功能,特别是考虑到未来可能存在只有单个HTML 文件的Web Components 的情况。
API 范式
最后一个标准类别与我之前讨论的所有内容有些不同。
这些标准涉及Web Components 的基本编程范式。
Web Components v1 主要是一种命令式的JavaScript 编程模型。
有一些值得注意的例外,比如声明式的slot 分配。
但基本上,它完全是命令式的。
自v1 以来,我们一直在努力引入越来越多的声明式特性。
其中一个很好的例子是声明式Shadow DOM。
总的来说,最好为所有场景提供声明式和命令式的API。
但最终目标是拥有某种完全声明式定义的Web Components,以便服务器可以向浏览器发送元素定义,在noscript 上下文中可以完全工作。
我们还有一段路要走,但当我们到达那里时,它将从根本上改变客户端和服务器开发。
下一步是什么标准的工作永远在进行中。
事实上,从今天开始,W3C Web 组件社区组正在召开其2023 年春季面对面活动。
就像TPAC 一样,这是一个机会,供库作者、组件创建者、浏览器厂商等聚集在一起,并花费专门的时间来解决仍需要共识或存在开放问题的规范的细节。
我期待在后续的博客文章中向大家更新活动结果。
总结
我希望本次的 Web Components 标准之旅对你来说是有意义的。
你看到我们已经走了多远,未来还有什么等待我们,这很有趣。
随着v1 版本的发布,过去几年中已经发布的功能翻了一番,以及即将到来令人兴奋的新功能,现在是成为Web 开发人员的好时机。