Shadow DOM 是不是像 React.js 中的 Virtual DOM 一样快?

Posted

技术标签:

【中文标题】Shadow DOM 是不是像 React.js 中的 Virtual DOM 一样快?【英文标题】:Is Shadow DOM fast like Virtual DOM in React.js?Shadow DOM 是否像 React.js 中的 Virtual DOM 一样快? 【发布时间】:2016-06-30 22:47:07 【问题描述】:

在我的项目中实现 Shadow DOM 是否会让它们像 React 使用的虚拟 DOM 一样更快?

【问题讨论】:

【参考方案1】:

不,Shadow DOM 和 Virtual DOM 无关,尽管名称有些相似:

虚拟 DOM: 出于不同的原因,保留 DOM 的两个副本(原始的和更新的)的 React 概念。在渲染之前,React 对这两个对象进行比较以确定它是否应该对实际的 DOM 树应用更新。这会提高性能,因为我们只更新需要它的视图部分,而不是整个屏幕。

Shadow DOM: W3C 提出的Web Components spec 的一部分,它基本上允许将较小的 DOM 元素和 CSS 样式封装到单个 DOM 元素中:

Shadow DOM 元素示例

<my-video   />

但是&lt;my-video&gt;实际上封装了以下元素:

<div>
   <input type="button" style="color: blue;">Play
   <input type="button" style="color: red;">Pause
   <source src="myVideo.mp4">
</div>

因此,通过使用 Shadow DOM,我们能够隐藏 Web 元素的实现细节,并且只将必要的信息传递给子元素(即heightwidth),这可能令人困惑,非常类似于将 props 传递给组件的 ReactJS 习惯用法。

通过提供的信息:

http://www.funnyant.com/reactjs-what-is-it/ http://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/

【讨论】:

你的意思是Shadow DOM的性能和DOM一样,只是被封装了? @Hmoo_oomH 我的理解是Shadow DOM更多是为了可读性 - 因为我们将复杂Web元素的实现细节隐藏在高阶元素(例如&lt;video&gt;)之后,但没有期望性能提升。 认为这必须是 &lt;video-element&gt; 或类似的连字符名称【参考方案2】:

虚拟 DOM

虚拟 DOM 旨在避免对 DOM 进行不必要的更改,这在性能方面是昂贵的,因为对 DOM 的更改通常会导致页面重新呈现。虚拟 DOM 还允许收集多个更改以同时应用,因此并非每个更改都会导致重新渲染,而是仅在对 DOM 应用一组更改后才发生一次重新渲染。

阴影 DOM

Shadow dom 主要是关于实现的封装。单个自定义元素可以实现或多或少复杂的逻辑与或多或少复杂的 DOM 相结合。可以通过导入和&lt;body&gt;&lt;my-app&gt;&lt;/my-app&gt; 将任意复杂度的整个 Web 应用程序添加到页面中,但也可以将更简单的可重用和可组合组件实现为自定义元素,其中内部表示隐藏在影子 DOM 中,例如 &lt;date-picker&gt;&lt;/date-picker&gt;

样式封装 Shadow DOM 还可以防止样式被意外应用于设计者不打算使用的元素,例如,因为您正在使用的 CSS 或组件库更改了一个选择器,该选择器现在适用于使用相同 CSS 类名称的其他元素。添加到组件的样式被限定在该组件的范围内,并防止样式流出或流入。

Shadow DOM 和性能

尽管影子 DOM 与性能无关,但它也对性能有影响。因为样式是有范围的,所以浏览器可以假设某些更改仅影响页面的有限区域(自定义元素的影子 DOM),这可以限制重新渲染到此类组件的区域,而不是重新渲染整个页面。

这就是 &gt;&gt;&gt;/deep/::shadow CSS 组合器(允许跨阴影 DOM 边界应用样式)被弃用并很快会从 Chrome 中删除的原因(其他浏览器从未有过)据我所知)。仅仅这些组合器的存在就阻止了上一段中提到的那种优化。

Angular2 使用了两者的优势。

它使用单向数据流并仅在模型上运行更改检测。如果它检测到更改,它会通过更新绑定来更新 DOM,并生成像 *ngFor*ngIf、...这样的结构指令来更新 DOM。因此,DOM 仅在模型实际更改时才更新。

Angular2 使用 shadow DOM(仅使用 ViewEncapsulation.Native,目前不是默认的)来利用浏览器提供的样式封装功能,或者(当前默认)只是通过重写添加到组件的样式来模拟样式封装,作为一种解决方法,直到原生 shadow DOM 和 CSS 变量(用于动态全局样式更改)变得广泛可用。

【讨论】:

...而且 DOM 并不慢。你是。 korynunn.wordpress.com/2013/03/19/the-dom-isnt-slow-you-are 一些实用的答案可能会增加更多的意义。 @Code 你错过了什么意思?一般来说,关于性能的问题通常是毫无意义的。如果您确实需要了解,请建立一个涵盖您的用例的基准。 这是信息;但是,它没有回答这个问题。 A 和 B 一样快吗?某处应该有“是”或“否”,或者可以很容易地推断出答案的陈述,或者可以纠正问题所基于的错误前提。

以上是关于Shadow DOM 是不是像 React.js 中的 Virtual DOM 一样快?的主要内容,如果未能解决你的问题,请参考以下文章

基于 Shadow DOM 根的字体大小 css-values

React.js - 目标容器不是DOM元素

Shadow DOM 是不是能够保护元素?

IOS Safari 是不是支持 Shadow DOM?

是否可以通过父文档访问 Shadow DOM 元素?

聚合:将样式应用于Shadow DOM下的元素