在页面中如何大面积操作DOM的话,性能肯定是一个很大的问题,然而聪明的ReactJS实现了Virtual DOM技术,这是他的亮点之一。将组件的DOM结构映射到这个Virtual DOM对象上,并且ReactJS还实现了一套Diff算法,这也是他亮点之一。当需要更新组件的时候,会通过Diff算法找到要变更的内容,最后,在把这个修改更新到实际的DOM节点上,所以,组件更新实际上不是真的渲染整个DOM树,而是指更新需要修改的DOM节点,这样在性能上会比原生DOM快很多。
那么这个Virtual DOM到底是什么?假设我们要创建一个组件,其结构如下:
1 <ul> 2 <li> 3 A 4 </li> 5 <li> 6 <ul> 7 <li> 8 B 9 </li> 10 </ul> 11 </li> 12 </ul>
然后我们开始创建原生组件:
1 //用JSX实现的 2 var root = <ul> 3 <li>A</li> 4 <li> 5 <ul> 6 <li> 7 B 8 </li> 9 </ul> 10 </li> 11 </ul>; 12 //用javascript实现的 13 var A = React.createElement('li',null,'A'); 14 var B = React.createElement('ul',null,React.createElement('li',null,'B')); 15 var root = React.createElement('ul',null,A,B); 16 //输出虚拟的DOM结构 17 console.log(root);
打开控制台我们就能看到输出的一个javascript的对象,没错这就是我们所说的Virtual DOM对象;
接下来我们看看Diff算法在ReactJS中的体现,首先我们借助浏览器中的MutationObderver功能,对页面元素进行监听
1 'use strict'; 2 const mutation = window.MutationObserver 3 ||window.WebKitMutationObserver 4 ||window.MozMutationObserver; 5 if(!!mutation){ 6 const mutationObserver = new mutation((item) => { 7 item.forEach((item) => { 8 console.log(item); 9 }); 10 }); 11 const options = { 12 "childList" : true, 13 "attributes" : true, 14 "characterData" : true, 15 "subtree" : true, 16 "attributeOldValue" : true, 17 "characterDataOldValue" : true 18 }; 19 mutationObserver.observe(document.body,options); 20 }