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


Answers:


125

虚拟DOM

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

影子DOM

Shadow dom主要与实现的封装有关。单个定制元素可以实现与或多或少的复杂DOM相结合的或多或少的复杂逻辑。可以通过导入将任意复杂度的整个Web应用程序添加到页面上,<body><my-app></my-app>而且还可以将更简单的可重用和可组合组件实现为自定义元素,其中内部表示形式隐藏在影子DOM中<date-picker></date-picker>

样式封装 Shadow DOM还可以防止样式被意外地应用到设计人员不想要的元素上,例如,因为您使用的CSS或组件库更改了一个选择器,该选择器现在可应用于使用相同CSS类名的其他元素。添加到组件的样式的作用域仅限于该组件,可以防止样式渗出或渗入。

影子DOM和性能

即使影子DOM最初与性能无关,它也具有性能影响。因为样式是作用域的,所以浏览器可以对某些更改做出假设,以仅影响页面的有限区域(自定义元素的阴影DOM),从而可以将重新呈现限制为此类组件的区域,而不是重新呈现整个页面。

这就是原因>>>/deep/::shadowCSS组合程序,这使得跨影子DOM边界应用样式,已过时,受到从Chrome很快删除(其他浏览器永远得不到据我所知)。这些组合器的存在阻碍了上一段中提到的优化。

Angular2利用了两个世界的优势。

它使用单向数据流,并且仅在模型上运行更改检测。如果检测到变化它会导致DOM被更新的绑定更新,并作出这样结构的指令*ngFor*ngIf...更新DOM。因此,仅在实际更改模型时才更新DOM。

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



一些实际的答案可能会增加更多的意义。
代码

@Code您缺少什么意思?通常,有关性能的问题通常毫无意义。如果您真的需要知道,请建立一个涵盖您的用例的基准。
君特Zöchbauer

70

不,Shadow DOM和Virtual DOM是无关的,尽管它们的名称有些类似:

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

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

阴影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>

因此,通过使用影子DOM,我们能够隐藏我们的Web元素的实现细节,只沿必要的信息传递到子元素(即heightwidth),这或许令人混淆,外观极像ReactJS成语传球props到组件。

通过以下方式提供的信息


您是说Shadow DOM的性能就像DOM一样,但是只是封装了吗?
Hmoo_oomH 2016年

3
@Hmoo_oomH我的理解是Shadow DOM更具可读性-因为我们将复杂的Web元素的实现细节隐藏在一个高阶元素(例如<video>)之后,但是并没有提高性能的期望。
勒克斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.