92

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

4

2 回答 2

139

虚拟 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 类名的其他元素。添加到组件的样式的范围仅限于该组件,并且可以防止样式流出或流入。

Shadow DOM 和性能

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

这就是允许跨阴影 DOM 边界应用样式的、 和CSS 组合器被弃用的原因>>>,并且很快就会从 Chrome 中删除(其他浏览器从未有过它们的 AFAIK)。这些组合器的存在阻止了上一段中提到的那种优化。/deep/::shadow

Angular2使用了这两个世界的优点。

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

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

于 2016-04-28T05:48:04.497 回答
77

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

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

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

示例 Shadow DOM 元素

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

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

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

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

通过以下方式提供的信息

于 2016-03-15T14:49:43.880 回答