为什么选择我--ReactJS

在页面中如何大面积操作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 }

然后再把ReactJS组件的生命周期进行封装,便于组件来调用

 1 ‘use strict‘;
 2 const LifeCycle = name => {
 3     let obj = {
 4         name : name
 5     };
 6     return Object.assign(obj,Cycle);
 7 };
 8 const Cycle = {
 9     getDefaultProps:function(){
10         console.log(this.name,‘getDefaultProps‘);
11         return {};
12     },
13     getInitialState:function(){
14         console.log(this.name,‘getInitailState‘);
15         return {};
16     },
17     componentWillMount:function(){
18         console.log(this.name,‘componentWillMount‘);
19     },
20     componentDidMount:function(){
21         console.log(this.name,‘componentDidMount‘);
22     },
23     componentWillRecieveProps:function(){
24         console.log(this.name,‘componentWillRecieveProps‘);
25     },
26     shouldComponentUpdate:function(){
27         console.log(this.name,‘shouldComponentUpdate‘);
28         return true;
29     },
30     componentWillUpdate:function(){
31         console.log(this.name,‘componentWillUpdate‘);
32     },
33     componentDidUpdate:function(){
34         console.log(this.name,‘componentDidUpdate‘);
35     },
36     componentWillUnmount:function(){
37         console.log(this.name,‘componentWillUnmount‘);
38     }
39 }; 

接着定义需要用到的组件

 1 ‘use strict‘;
 2 //A组件
 3 let A = React.createClass({
 4     mixins:[LifeCycle(‘A‘)],
 5     render:function(){
 6         console.log(‘A‘,‘render‘);
 7         return (
 8             <ul>
 9                 <li>A</li>
10                 <li>
11                     <ul>
12                         {this.props.children}
13                     </ul>
14                 </li>
15             </ul>
16         );
17     }
18 });
19 //B组件
20 let B = React.createClass({
21     mixins:[LifeCycle(‘B‘)],
22     render:function(){
23         console.log(‘B‘,‘render‘);
24         return (
25             <li>B</li>
26         );
27     }
28 });
29 //C组件
30 let C = React.createClass({
31     mixins:[LifeCycle(‘C‘)],
32     render:function(){
33         console.log(‘C‘,‘render‘);
34         return (
35             <li>C</li>
36         );
37     }
38 });
39 //D组件
40 let D = React.createClass({
41     mixins:[LifeCycle(‘D‘)],
42     render:function(){
43         console.log(‘D‘,‘render‘);
44         return (
45             <li>D</li>
46         );
47     }
48 });

最后,定义我们的主逻辑

 1 console.log(‘----------------first-----------------‘);
 2 React.render(
 3     <A><B></B><C></C></A>,
 4     document.body
 5 );
 6
 7 setTimeout(() => {
 8     console.log(‘-----------------second--------------‘);
 9     React.render(
10         <A><B></B><D></D><C></C></A>,
11         document.body
12     );
13 },1000);

常规的做法就是将B和C组件先删除,然后依次创建和插入A,B,C组件。接下来我们打开浏览器的控制台看下ReactJS是怎么做的

          

从日志中可以看出,React的Diff算法的结果是,A组件不变,先将C组件进行删除,然后在创建D组件并插入D组件,最后创建并插入C组件,这比我们常规的做法省去了对B组件的删除操作。这样其实并没有将Diff算法的作用发挥到极限。下面我们调整下逻辑代码:

 1 console.log(‘----------------first-----------------‘);
 2 React.render(
 3     <A key="A"><B key="B"></B><C key="C"></C></A>,
 4     document.body
 5 );
 6
 7 setTimeout(() => {
 8     console.log(‘-----------------second--------------‘);
 9     React.render(
10         <A key="A"><B key="B"></B><D key="D"></D><C key="C"></C></A>,
11         document.body
12     );
13 },1000);

主要的修改就是给每个组件加了一个key属性,此时再来运行下代码看下控制台的日志:

       

可以看出,这次Diff算法与之前的有很大的不同。B组件不变,C组件不变,只是在C组件之前创建并插入了D组件。

以上便是Virtual DOM和Diff算法的一些简单的使用和分析,学习来源:

http://calendar.perfplanet.com/2013/diff/ 《React Native入门与实践》

时间: 2024-10-11 11:09:02

为什么选择我--ReactJS的相关文章

D1.1.利用npm(webpack)构建基本reactJS项目

前提: 已经安装nodejs和npm #全局安装webpack 自动构建化工具,职能管理项目:webpack-dev-server是开发工具,提供 Hot Module Replacement 功能# webpack 介绍:http://webpack.github.io/docs/what-is-webpack.html npm install -g webpack webpack-dev-server #在项目文件夹路径下,初始化npm项目 npm init #安装webpack和webpa

一看就懂的ReactJs入门教程(精华版)

现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~ 一.ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西很好用

我为什么选择go语言

这里,我并不打算引起语言争论的口水仗,我并不是什么大牛,对语言的造诣也不深,只是想通过自己实际的经历,来说说为什么我在项目中选择go. 其他语言的经历 C++ 在接触go之前,我已经有多年的c++开发经验.主要用在游戏服务端引擎开发以及P2P上面,那可是一段痛并快乐的时期,以至于我看到任何的程序钉子问题都觉得可以用c++这把锤子给敲定.但是对于互联网项目开发来说,除非你的团队整体的c++技术水平nb,并且有很强的代码规范,不然真可能是一场灾难,更别说我们现有团队几乎没其他人会这玩意了. 本来,我

ReactNative入门(1)初识ReactJs

现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJS的风采吧~~ 章有点长,耐心读完,你会有很大收获哦~ 一.ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西很好用

初级前端自学react-native,必备知识点(ES6+ReactJS+flexbox)

我们在学会搭建react-native环境之后,打开项目根目录,看到很多个文件,但是最起眼的应该就是那俩js兄弟文件了 我们一看那名字就知道,我们接下来的任务就是要弄它们: 我们用编辑器打开项目根目录下的index.android.js文件,可以看到有这么个东西: 那么我们先测试一下,在手机上跑起来.不知道大家还记不记得步骤: 第一步:在项目根目录下打开两个git bash.第一个输入:react-native start        这一步是在启用服务器 第二步:在第一步成功之后,连接手机,

ReactJs

这周二学习了ReactJs,颠覆了之前学习的思路. React 起源于 Facebook 的内部项目,就在2013年5月开源了.代码逻辑简单,但是思维方式,我一时间有点转换不过来. 一.填空题 1.ReactJs不是一个____________,而是一个_________,可以视为mvc中的__________. 2.ReactJs的两个特点是:__________________和____________________. 3.React.render(<h1>Hello,world<

ReactJS ,是否言过其实?

最近前端大热,各种MVC框架层出不穷,大有百鸟争鸣之意. 这"百鸟"中,数ReactJS尤其火热,出身高贵,一面世就引起关注! 之后Facebook更是宣称支持构建安卓以及苹果原生应用,这对很多烦恼于多平台的企业更是一场及时雨! 但是事实真的如此吗?我在[如何选择框架]一文中讲过,做过程序员的,对一些词语根本没有招架之力,比如丝袜,滴蜡,皮鞭..... 不好意思,讲错,是跨平台,企业级解决方案,技术规范... 如果你在选择一款框架时,仅仅看官方的介绍,或者看百度上排名第一的软文,那你只

ReactJS入门二

ReactJS入门学习二 ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用样式 回到顶部 React的背景和基本原理 在web开发中,我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作,复杂或频繁的对DOM操作是性能瓶颈产生的原因,React为此引入了虚拟的DOM的机制,在浏览器端使用javascript实现了一套DOM API,

ReactJS入门

ReactJS入门学习一 阅读目录 React是什么? React如何制作组件? 理解组件属性props 理解页面中如何渲染数据的 理解从服务器端获取数据及理解state的 回到顶部 React是什么? React仅仅是VIEW层,而我们经常看到Angular是一个完整的框架,而React不是,因此我们看到他们两个的侧重点不一样,所以也不能比较的,React提供了模板语法及一些函数钩子用于HTML的渲染,只用于View层. React的优点?       1. 虚拟DOM 在DOM树的状态发生改