Shadow DOM在React.js中是否像Virtual DOM一样快?

时间:2016-03-15 13:08:23

标签: javascript dom web-component shadow-dom virtual-dom

在我的项目中实施Shadow DOM会使它们像React使用的虚拟DOM一样快吗?

3 个答案:

答案 0 :(得分:103)

虚拟DOM

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

暗影DOM

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

样式封装 Shadow DOM还涉及防止样式被意外地应用于设计者不想要的元素,例如因为您使用的CSS或组件库改变了现在应用于使用相同CSS类名的其他元素的选择器。添加到组件的样式作用于该组件,防止出现样式或样式。

影子DOM和效果

尽管影子DOM首先与性能无关,但它也具有性能影响。由于样式是作用域的,浏览器可以对某些更改进行假设,以仅影响页面的有限区域(自定义元素的阴影DOM),这可能会限制重新渲染到此类组件的区域,而不是重新渲染整个页面。

这就是<date-picker></date-picker>>>>/deep/ CSS组合器允许在阴影DOM边界内应用样式的原因已被弃用,并且很快就会从Chrome中删除(其他浏览器从来没有他们AFAIK)。仅仅存在这些组合器就会阻止前一段中提到的那种优化。

Angular2 利用两个世界的优势。

它使用单向数据流并仅在模型上运行更改检测。如果它检测到更改,则会通过更新绑定来更新DOM,并使::shadow*ngFor等结构指令更新DOM。因此,DOM仅在模型实际更改时更新。

Angular2使用shadow DOM(只有*ngIf,目前不是默认值)来利用浏览器提供的样式封装功能,或者(当前默认)只是通过重写添加到组件的样式来模拟样式封装,如解决方法直到本机阴影DOM和CSS变量(用于动态全局样式更改)变得广泛可用。

答案 1 :(得分:58)

不,Shadow DOM和Virtual DOM是不相关的,虽然有点类似名称:

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

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

Shadow DOM元素示例

<video width="300" height="150" />

但是,<video>实际上封装了以下元素:

<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惯用法。

通过提供的信息:

答案 2 :(得分:-6)

在此测试中,Polymer吹响了Chrome中的性能:

https://jsperf.com/polymer-vs-react-update/6