Shadow DOM是否像React.js中的虚拟DOM一样快?
在我的项目中实现Shadow DOM会使它们像React使用的虚拟DOM一样快吗?
虚拟DOM
虚拟DOM将避免对DOM进行不必要的更改,这在性能上是非常昂贵的,因为对DOM的更改通常会导致页面重新呈现。 虚拟DOM还允许收集一些要一次应用的更改,因此不是每一次更改都会导致重新呈现,而是在将一组更改应用到DOM之后,只会重新呈现一次。
影子DOM
影子主要是关于实现的封装。 一个自定义元素可以实现与或多或less复杂DOM相结合的或多或less的复杂逻辑。 可以通过导入和<body><my-app></my-app>
将任意复杂度的整个Web应用程序添加到页面中,但也可以将更简单的可重用和可组合元素实现为隐藏内部表示forms的自定义元素在像<date-picker></date-picker>
这样的阴影DOM中。
样式封装 Shadow DOM也是关于防止样式意外地应用到devise人员不打算的元素,例如,因为您正在使用的CSS或组件库更改了一个select器,现在适用于使用相同CSS类名称的其他元素。 添加到组件的样式被限定在该组件中,并防止了样式出血或样式错误。
影子DOM和性能
尽pipe影子DOM并不是首先关注性能,但它也有性能影响。 由于样式是作用域的,因此浏览器可以对某些更改进行假设,以仅影响页面的有限区域(自定义元素的阴影DOM),这会限制对此组件的区域进行重新渲染,而不是重新渲染整个页面。
这就是>>>
, /deep/
和::shadow
CSS组合器,允许跨阴影DOM边界应用样式的原因已被弃用,并且很快就会从Chrome中删除(其他浏览器从来没有AFAIK)。 这些组合器的存在阻止了前面提到的那种优化。
Angular2使用两个世界的优点。
它使用单向数据stream,只在模型上运行变化检测。 如果它检测到更改,则会通过更新绑定并使结构指令(如*ngFor
, *ngIf
,…)更新DOM来更新DOM。 因此,只有当模型实际改变时才更新DOM。
Angular2使用了影子DOM(目前不是默认的ViewEncapsulation.Native
)来利用浏览器提供的样式封装function,或者(当前默认)只是通过重写添加到组件的样式来模拟样式封装,直到原生影子DOM和CSSvariables(用于dynamic全局样式变化)变得广泛可用。
不,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>
所以通过使用Shadow DOM,我们可以隐藏web元素的实现细节,并只传递必要的信息给子元素(即height
, width
),这或许令人困惑,非常类似于ReactJS的成语props
组件。
信息提供 :
从这个testing中,聚合物在Chrome中的性能反弹: