技术文

React中一个没人能解释清楚的问题——为什么要使用Virtua

2016-09-07  本文已影响158人  51CTO学院

译者:TinkGu
链接:http://www.zcfy.cc/article/1211
原文:https://hashnode.com/post/the-one-thing-that-no-one-properly-explains-about-react-why-virtual-dom-cisczhfj41bmssp53mvfwmgrq

有一天,我的朋友向我提了一个有关React的问题:

组件化, 单向数据绑定,这些我都懂了。但是React为什么要用Virtual DOM呢?

我的回答非常套路,“因为直接操作DOM比较低效,比较慢。”。

“但是现在的js引擎总是搞个大新闻,说自己的性能比之前又要不知道高到哪里去了。既然如此,为什么还会说直接操作DOM比较慢呢?”

好吧... 这确实是一个好问题。

惊人的是,我找了半天,发现并没有任何一篇文章可以给出坚如磐石的证明,来完满地解释Virtual DOM的必要性。
其实,使得整个流程变得低效的,并不只有直接操作DOM,还包括了操作DOM之后发生的事情。

为了能让你更好地理解Virtual DOM的必要性,我们先来个急转弯,从宏观上来看浏览器的工作流。以及,一次DOM更新后,到底会发生什么事呢?

浏览器工作流

NOTE:在下面这张图中,配图文字使用的是Webkit引擎的术语。所有的浏览器都是遵循类似的工作流,仅在细节处略有不同。

浏览器工作流浏览器工作流

创建DOM树

创建渲染树

创建渲染树背后的故事

布局 Layout

又被简称为Reflow[2]

绘制 Painting

再来看Virtual DOM

好啦,现在你已经简单过了一遍浏览器引擎的渲染流程,你可以看到,从创建渲染树,到布局,一直到绘制,只要你在这过程中进行一次DOM更新,整个渲染流程都会重做一遍。尤其是创建渲染树,它需要重新计算所有元素上的所有样式。

在一个复杂的单页面应用中,经常会涉及到大量的DOM操作,这将引起多次计算,使得整个流程变得低效,这应该尽量避免。

Virtual DOM这个抽象层真正的闪光点正在于此:每当你想对视图进行一次更新,那些本该直接作用于真实DOM的改动,都会先作用于Virtual DOM,然后再将要改动的部分通知到真实DOM。这样可以大幅减少DOM操作带来的重计算步骤。

Update: Reddit上的 ugwe43to874nf4 对Virtual DOM的重要性做了更客观的评价。

DOM 操作 真正的问题在于每次操作都会触发布局的改变、DOM树的修改和渲染。所以,当你一个接一个地去修改30个节点的时候,就会引起30次(潜在的)布局重算,30次(潜在的)重绘,等等。

Virtual DOM 实际上没有使用什么全新的技术,仅仅是把 “ 双缓冲(double buffering)” 技术应用到了DOM上面。
这样一来,当你在这个单独的虚拟的DOM树上也一个接一个地修改30个节点的时候,它不会每次都去触发重绘,所以修改节点的开销就变小了。
之后,一旦你要把这些改动传递给真实DOM,之前所有的改动就会整合成一次DOM操作。这一次DOM操作引起的布局计算和重绘可能会更大,但是相比而言,整合起来的改动只做一次,减少了(多次)计算。

不过,实际上不借助Virtual DOM也可以做到这一点。你可以自己手动地整合所有的DOM操作到一个DOM 碎片(DOM fragment) 里,然后再传递给DOM树。

既然如此,我们再来看看Virtual DOM到底解决了什么问题。
首先,它把管理DOM碎片这件事情自动化、抽象化了,使得你无需再去手动处理。另外,当你要手动去做这件事情的时候,你还得记得哪些部分变化了,哪些部分没变,毕竟之后重绘时,DOM树上的大量细节你都不需要重新刷新。这时候Virtual DOM的自动化对你来说就非常有用了,如果它的实现是正确的,那么它就会知道到底哪些地方应该需要刷新,哪些地方不要。

最后,Virtual DOM通过各种组件和你写的一些代码来请求对它进行操作,而不是直接对它本身进行操作,使你不必非要跟Virtual DOM交互,也不必非要去了解Virtual DOM修改DOM树的原理,也就不用再想着去修改DOM了。(译注:对开发者来说,Virtual DOM几乎是完全透明的)。这样你就不用在 修改DOM整合DOM操作为一次 之间做同步处理了。

进一步阅读

以上关于浏览器工作流的内容摘录自这篇文档中关于浏览器内部行为的章节。这篇文章还深入解释了浏览器引擎的hood部分的一切细节。毋庸置疑,这篇文章值得你花时间从头到尾好好读一遍。它会帮你很好地理解为什么我们需要Virtual DOM这样一个额外的抽象层。

译注

上一篇 下一篇

猜你喜欢

热点阅读