Shadow DOM 是否像 React.js 中的 Virtual DOM 一样快?
Is Shadow DOM fast like Virtual DOM in React.js?
在我的项目中实施 Shadow DOM 是否会使它们像 React 使用的虚拟 DOM 一样更快?
不,Shadow DOM 和 Virtual DOM 无关,尽管名称有些相似:
Virtual DOM: React 的概念是出于不同的原因保留 DOM 的两个副本(原始的和更新的)。在渲染之前,React 比较这两个对象以确定它是否应该将更新应用于实际的 DOM 树。这会提高性能,因为我们只更新需要它的视图部分,而不是整个屏幕。
Shadow DOM: W3C 提议的 Web Components spec 的一部分,它基本上允许封装更小的 DOM 元素和 CSS 样式到单个 DOM 元素中:
示例阴影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
),这可能令人困惑,它非常类似于将 props
传递给组件的 ReactJS 习惯用法。
信息通过提供:
虚拟DOM
虚拟 DOM 是为了避免对 DOM 进行不必要的更改,这在性能方面是昂贵的,因为对 DOM 的更改通常会导致页面重新呈现。 Virtual DOM 还允许收集要同时应用的多个更改,因此并非每个更改都会导致重新渲染,而是在将一组更改应用于 [=56= 之后重新渲染只会发生一次].
阴影DOM
影子dom主要是关于实现的封装。单个自定义元素可以实现或多或少的复杂逻辑以及或多或少的复杂性 DOM。可以通过导入和 <body><my-app></my-app>
将任意复杂度的整个 Web 应用程序添加到页面,但也可以将更简单的可重用和可组合组件实现为自定义元素,其中内部表示隐藏在阴影中 DOM,例如<date-picker></date-picker>
.
样式封装
Shadow DOM 也是为了防止样式被意外应用到设计者不打算应用的元素,例如,因为 CSS 或您正在使用的组件库更改了一个选择器,该选择器现在应用于其他使用的元素相同的 CSS class 名称。添加到组件的样式限定在该组件范围内,防止样式渗出或渗入。
阴影DOM和性能
尽管 shadow DOM 首先与性能无关,但它也对性能有影响。因为样式是有范围的,所以浏览器可以假设某些更改只影响页面的有限区域(自定义元素的阴影 DOM),这可以限制对此类组件区域的重新渲染,而不是重新呈现整个页面。
这就是 >>>
、/deep/
和 ::shadow
CSS 组合器允许跨阴影 DOM 边界应用样式的原因已弃用,很快就会从 Chrome 中删除(其他浏览器从未有过它们 AFAIK)。这些组合器的存在阻止了上一段中提到的那种优化。
Angular2 利用了两个世界的优点。
它使用单向数据流并仅在模型上运行变化检测。如果它检测到更改,它会导致 DOM 通过更新绑定进行更新,并使结构指令如 *ngFor
、*ngIf
、...更新 DOM。因此 DOM 仅在模型实际更改时更新。
Angular2 使用 shadow DOM(仅 ViewEncapsulation.Native
目前不是默认的)来利用浏览器提供的样式封装功能,或者(当前默认)通过重写样式来模拟样式封装添加到组件中,作为一种解决方法,直到本机阴影 DOM 和 CSS 变量(用于动态全局样式更改)变得广泛可用。
在我的项目中实施 Shadow DOM 是否会使它们像 React 使用的虚拟 DOM 一样更快?
不,Shadow DOM 和 Virtual DOM 无关,尽管名称有些相似:
Virtual DOM: React 的概念是出于不同的原因保留 DOM 的两个副本(原始的和更新的)。在渲染之前,React 比较这两个对象以确定它是否应该将更新应用于实际的 DOM 树。这会提高性能,因为我们只更新需要它的视图部分,而不是整个屏幕。
Shadow DOM: W3C 提议的 Web Components spec 的一部分,它基本上允许封装更小的 DOM 元素和 CSS 样式到单个 DOM 元素中:
示例阴影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
),这可能令人困惑,它非常类似于将 props
传递给组件的 ReactJS 习惯用法。
信息通过提供:
虚拟DOM
虚拟 DOM 是为了避免对 DOM 进行不必要的更改,这在性能方面是昂贵的,因为对 DOM 的更改通常会导致页面重新呈现。 Virtual DOM 还允许收集要同时应用的多个更改,因此并非每个更改都会导致重新渲染,而是在将一组更改应用于 [=56= 之后重新渲染只会发生一次].
阴影DOM
影子dom主要是关于实现的封装。单个自定义元素可以实现或多或少的复杂逻辑以及或多或少的复杂性 DOM。可以通过导入和 <body><my-app></my-app>
将任意复杂度的整个 Web 应用程序添加到页面,但也可以将更简单的可重用和可组合组件实现为自定义元素,其中内部表示隐藏在阴影中 DOM,例如<date-picker></date-picker>
.
样式封装 Shadow DOM 也是为了防止样式被意外应用到设计者不打算应用的元素,例如,因为 CSS 或您正在使用的组件库更改了一个选择器,该选择器现在应用于其他使用的元素相同的 CSS class 名称。添加到组件的样式限定在该组件范围内,防止样式渗出或渗入。
阴影DOM和性能
尽管 shadow DOM 首先与性能无关,但它也对性能有影响。因为样式是有范围的,所以浏览器可以假设某些更改只影响页面的有限区域(自定义元素的阴影 DOM),这可以限制对此类组件区域的重新渲染,而不是重新呈现整个页面。
这就是 >>>
、/deep/
和 ::shadow
CSS 组合器允许跨阴影 DOM 边界应用样式的原因已弃用,很快就会从 Chrome 中删除(其他浏览器从未有过它们 AFAIK)。这些组合器的存在阻止了上一段中提到的那种优化。
Angular2 利用了两个世界的优点。
它使用单向数据流并仅在模型上运行变化检测。如果它检测到更改,它会导致 DOM 通过更新绑定进行更新,并使结构指令如 *ngFor
、*ngIf
、...更新 DOM。因此 DOM 仅在模型实际更改时更新。
Angular2 使用 shadow DOM(仅 ViewEncapsulation.Native
目前不是默认的)来利用浏览器提供的样式封装功能,或者(当前默认)通过重写样式来模拟样式封装添加到组件中,作为一种解决方法,直到本机阴影 DOM 和 CSS 变量(用于动态全局样式更改)变得广泛可用。