为什么选择我--ReactJS
在页面中如何大面积操作DOM的话,性能肯定是一个很大的问题,然而聪明的ReactJS实现了Virtual DOM技术,这是他的亮点之一。将组件的DOM结构映射到这个Virtual DOM对象上,并且ReactJS还实现了一套Diff算法,这也是他亮点之一。当需要更新组件的时候,会通过Diff算法找到要变更的内容,最后,在把这个修改更新到实际的DOM节点上,所以,组件更新实际上不是真的渲染整个DOM树,而是指更新需要修改的DOM节点,这样在性能上会比原生DOM快很多。
那么这个Virtual DOM到底是什么?假设我们要创建一个组件,其结构如下:
<ul>
<li>
A
</li>
<li>
<ul>
<li>
B
</li>
</ul>
</li>
</ul>
然后我们开始创建原生组件:
//用JSX实现的
var root = <ul>
<li>A</li>
<li>
<ul>
<li>
B
</li>
</ul>
</li>
</ul>;
//用javascript实现的
var A = React.createElement('li',null,'A');
var B = React.createElement('ul',null,React.createElement('li',null,'B'));
var root = React.createElement('ul',null,A,B);
//输出虚拟的DOM结构
console.log(root);
打开控制台我们就能看到输出的一个javascript的对象,没错这就是我们所说的Virtual DOM对象;
接下来我们看看Diff算法在ReactJS中的体现,首先我们借助浏览器中的MutationObderver功能,对页面元素进行监听
'use strict';
const mutation = window.MutationObserver
||window.WebKitMutationObserver
||window.MozMutationObserver;
if(!!mutation){
const mutationObserver = new mutation((item) => {
item.forEach((item) => {
console.log(item);
});
});
const options = {
"childList" : true,
"attributes" : true,
"characterData" : true,
"subtree" : true,
"attributeOldValue" : true,
"characterDataOldValue" : true
};
mutationObserver.observe(document.body,options);
}
然后再把ReactJS组件的生命周期进行封装,便于组件来调用
'use strict';
const LifeCycle = name => {
let obj = {
name : name
};
return Object.assign(obj,Cycle);
};
const Cycle = {
getDefaultProps:function(){
console.log(this.name,'getDefaultProps');
return {};
},
getInitialState:function(){
console.log(this.name,'getInitailState');
return {};
},
componentWillMount:function(){
console.log(this.name,'componentWillMount');
},
componentDidMount:function(){
console.log(this.name,'componentDidMount');
},
componentWillRecieveProps:function(){
console.log(this.name,'componentWillRecieveProps');
},
shouldComponentUpdate:function(){
console.log(this.name,'shouldComponentUpdate');
return true;
},
componentWillUpdate:function(){
console.log(this.name,'componentWillUpdate');
},
componentDidUpdate:function(){
console.log(this.name,'componentDidUpdate');
},
componentWillUnmount:function(){
console.log(this.name,'componentWillUnmount');
}
};
接着定义需要用到的组件
'use strict';
//A组件
let A = React.createClass({
mixins:[LifeCycle('A')],
render:function(){
console.log('A','render');
return (
<ul>
<li>A</li>
<li>
<ul>
{this.props.children}
</ul>
</li>
</ul>
);
}
});
//B组件
let B = React.createClass({
mixins:[LifeCycle('B')],
render:function(){
console.log('B','render');
return (
<li>B</li>
);
}
});
//C组件
let C = React.createClass({
mixins:[LifeCycle('C')],
render:function(){
console.log('C','render');
return (
<li>C</li>
);
}
});
//D组件
let D = React.createClass({
mixins:[LifeCycle('D')],
render:function(){
console.log('D','render');
return (
<li>D</li>
);
}
});
最后,定义我们的主逻辑
console.log('----------------first-----------------');
React.render(
<A><B></B><C></C></A>,
document.body
); setTimeout(() => {
console.log('-----------------second--------------');
React.render(
<A><B></B><D></D><C></C></A>,
document.body
);
},1000);
常规的做法就是将B和C组件先删除,然后依次创建和插入A,B,C组件。接下来我们打开浏览器的控制台看下ReactJS是怎么做的
从日志中可以看出,React的Diff算法的结果是,A组件不变,先将C组件进行删除,然后在创建D组件并插入D组件,最后创建并插入C组件,这比我们常规的做法省去了对B组件的删除操作。这样其实并没有将Diff算法的作用发挥到极限。下面我们调整下逻辑代码:
console.log('----------------first-----------------');
React.render(
<A key="A"><B key="B"></B><C key="C"></C></A>,
document.body
); setTimeout(() => {
console.log('-----------------second--------------');
React.render(
<A key="A"><B key="B"></B><D key="D"></D><C key="C"></C></A>,
document.body
);
},1000);
主要的修改就是给每个组件加了一个key属性,此时再来运行下代码看下控制台的日志:
可以看出,这次Diff算法与之前的有很大的不同。B组件不变,C组件不变,只是在C组件之前创建并插入了D组件。
以上便是Virtual DOM和Diff算法的一些简单的使用和分析,学习来源:
http://calendar.perfplanet.com/2013/diff/ 《React Native入门与实践》
为什么选择我--ReactJS的更多相关文章
- 一看就懂的ReactJs入门教程-精华版
现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...
- 前端构建大法 Gulp 系列 (二):为什么选择gulp
系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...
- ReactJS webpack实现JS模块化使用的坑
从一个原生HTML/CSS/JS模式的网页改造到ReactJS模块化的结构,需要以下步骤: (1)引用ReactJS框架 ->(2)使用webpack 工具 -> (3)配置webpack ...
- reactjs 接入数据模型以及markdown语法的支持
页面如下: reactjs 数据接入,直接定义数据(json),如下: reactjs 数据接入,从服务器抓取数据(json),如下:
- 初探ReactJS.NET 开发
ReactJS通常也被称为"React",是一个刚刚在这场游戏中登场的新手.它由Facebook创建,并在2013年首次发布.Facebook认为React在处理SPA问题上可以成 ...
- ReactJs笔记
中文教程:http://reactjs.cn/ 实例: http://www.ruanyifeng.com/blog/2015/03/react.html
- redux的中间层 --reactjs学习
React只负责UI层,也就是我们通常在MVC框架中 所说的View层,所以在使用React开发中 我们得引入Redux 负责Model 一开始学习Redux的中间层 有点 摸不到头, 其实只要你注意 ...
- 初识ReactJs(一)
React的开发背景 ReactJS官网地址:http://facebook.github.io/react/ Github地址:https://github.com/facebook/react J ...
- D2.Reactjs 操作事件、状态改变、路由
下面内容代码使用ES6语法 一.组件的操作事件: 1.先要在组件类定义内定义操作事件的方法,如同event handler.若我需要监听在组件内的Button的点击事件onClick,首先定义监听方法 ...
随机推荐
- [BZOJ 1004] [HNOI2008] Cards 【Burnside引理 + DP】
题目链接:BZOJ - 1004 题目分析 首先,几个定义和定理引理: 群:G是一个集合,*是定义在这个集合上的一个运算. 如果满足以下性质,那么(G, *)是一个群. 1)封闭性,对于任意 a, b ...
- 使用Unity游戏引擎在IOS模拟器中运行的方法
在Unity编译IOS程序时,在Unity导航栏菜单中选择Edit->ProjectSettings ->Player(菜单项)选择IOS平台在下方SDK Version处选择运行设备为I ...
- eclipse设置字体大小
eclipse是我们常用的开发工具.eclipse中的默认字体往往并不满足我们的需要,我经常要调节一下它的大小或者换一下风格.eclipse中的字体大小怎么改变呢? 工具/原料 eclipse 方法/ ...
- CSS实现文字竖排 DIV CSS文字垂直竖列排版显示如何实现?
DIV CSS实现文字竖排排版显示兼容各大浏览器,让文字垂直竖列排版布局. 有时我们需要一段文字进行从上到下竖列排版,我们知道CSS样式中有一样式可以让其竖列排版,但所有浏览器不全兼容,逼不得已放弃. ...
- Spark、Shark集群安装部署及遇到的问题解决
1.部署环境 OS:Red Hat Enterprise Linux Server release 6.4 (Santiago) Hadoop:Hadoop 2.4.1 Hive:0.11.0 JDK ...
- bzoj1236
其实这道题目不难,主要要求我们有一个清晰地思路首先可以按位数讨论,这里我把1~9单独讨论了因为除了1位数,每个位数开头的数的开头数字1前面都是-号然后考虑位数的奇偶性当位数为奇数的时候比较简单举个例子 ...
- WordPress 开放重定向漏洞
漏洞名称: WordPress 开放重定向漏洞 CNNVD编号: CNNVD-201309-167 发布时间: 2013-09-13 更新时间: 2013-09-13 危害等级: 高危 漏洞类型: ...
- 【转】VMware Workstation 11 永久激活码key 非注册机
原文网址:http://www.landiannews.com/archives/12565.html 昨天我们发布了<跨越式提升:VMware Workstation 11 发布 附下载地址& ...
- WIA
一台扫描仪,实际上就是一个Device对象,因此,我们可以通过DeviceManager来“获取”这台设备的“引用”,然后通过得到的Device对象,执行相应的扫描工作.从而跳过了使用ShowAcqu ...
- Android protectionLevel
Android protectionLevel分4个级别: "normal" "dangerous" "signature" "s ...