在我的项目中实施Shadow DOM会使它们像React使用的虚拟DOM一样快吗?
答案 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元素的实现细节,并且只将必要的信息传递给子元素(即height
,width
) ,这可能令人困惑,非常类似于将props
传递给组件的ReactJS惯用法。
通过提供的信息:
答案 2 :(得分:-6)
在此测试中,Polymer吹响了Chrome中的性能: