如何实现 Virtual DOM(虚拟DOM)
发布在js类栏目2016年11月30日view:1869BrettBatReact
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

废话不多说,如果大家玩过、学过、看过、研究过react都会知道,react的一大优势就是虚拟DOM的实现,这个确实大大提升了页面的加载速度。

那么,首先你得知道什么是虚拟DOM。国外某文献的介绍是两个定义点,一:Virtual DOM 描述的是真实的 DOM;二,当 Virtual DOM 树有所变化之后,将会得到一个新的 Virtual DOM 树,算法将比较新旧的两棵 Virtual DOM 树,找到不同之处,仅将变化的部分反映在真实的 DOM 上。

先让我们来了解一下JavaScript下载DOM的历史。Chrome浏览器刚出来的时候,加载JavaScript的速度远远在ie和其他浏览器之上,后来经过竞争,浏览器加载JavaScript的速度都非常接近了。然而,对于DOM树的优化,浏览器厂商怎么也是搞不出更加优势的方案,之后当然是加载DOM的时候性能各种消耗,网页只要涉及到了DOM结构的都比拖慢运行速度。这个也是没有办法,因为DOM的设计就是这般的复杂,不像js。那么用js承接DOM就被叫成了虚拟DOM,我刚才是接触这个叫法的时候,我还以为它就不是一个DOM了,只是一个模仿的DOM(其实react就是管这个叫做虚拟DOM,他们没有DOM的概念,完全将界面和业务分开了,你做你的界面,我做我的业务,互不干扰)。

扯了那么多,那么应该如何实现这个虚拟DOM呢?

打个比方:DOM树如下:

 <ul class="list">
                <li>item 1</li>
               <li>item 2</li>
    </ul>

如果是用js写的话,那就是这个样子的:

{ type: ‘ul’, props: { ‘class’: ‘list’ }, children: [
  { type: ‘li’, props: {}, children: [‘item 1’] },
  { type: ‘li’, props: {}, children: [‘item 2’] }
] }

不清晰?没有问题,优化一下就好,

h1('ul', { 'class': 'list' },
 h('li', {}, 'item 1'),
 h('li', {}, 'item 2'), 
)

这个怎么来的?

function h(type, props, ...children) {
  return { type, props, children }
}

有没有很熟悉的赶脚?…children别问我这个是什么,我已经忘记了。

其实,如果是用js转译的话,这里就是:

React.createElement(‘ul’, { className: ‘list’ },
  React.createElement(‘li’, {}, ‘item 1’),
  React.createElement(‘li’, {}, ‘item 2’),
);

然后我们就可以快速实现了。

/** @jsx h */
const a = (

h(‘ul’, { className: ‘list’ }, h(‘li’, {}, ‘item 1’), h(‘li’, {}, ‘item 2’), ); );

这里需要注意的就是上边的注释, /** @jsx h */,相当于告诉babel,要将这些代码转译为h替代React.createElement。

是不是很简单?

其实,函数h执行的时候,就返回一个纯js的对象,也就是传说中的virtual DOM表达式了。也就是我们经常听到的吊炸天的虚拟DOM。如下:

const a = (
  { type: ‘ul’, props: { className: ‘list’ }, children: [
    { type: ‘li’, props: {}, children: [‘item 1’] },
    { type: ‘li’, props: {}, children: [‘item 2’] }
  ] }
);

这就是非常简单的虚拟DOM的实现啦,如果你想要了解更多的虚拟DOM可以点击我参考的文献。

参考文献一:如何实现 Virtual

参考文献二:深度剖析:如何实现一个 Virtual DOM 算法

评论
发表评论
2年前

@往返的扁舟 一起学习^_^

2年前

@luobo_tang 这个讲得还是比较跳跃了,以后写文章我还是查多些资料,逻辑紧凑一些吧。谢谢提醒!

2年前

这样讲别人是看不懂的吧….

一起理解 Virtual DOM http://www.jianshu.com/p/bef1c1ee5a0e

WRITTEN BY
往返的扁舟
一个符号不能代表什么;一堆符号能代表好多。
TA的新浪微博
PUBLISHED IN
js类栏目

js相关内容

我的收藏