React学习报告

React原理学习

React出身FaceBook豪门,一出生就带着virtualDOM和diff算法两大颠覆式的被动技能,很快引来高度关注,而且以高效快速著称。
通过一段时间的使用,抽出时间来学习其原理,发现并不难,可是想法很创新。造就了其不一样于传统框架的开发模式。html

1、VirtualDOM

VirtualDOM一直是React最著名,最神秘的特色。也是其高效迅速的核心。
virtualDOM其实很好理解:FaceBook的工程师认为传统的框架,频繁的操做DOM代价很大。性能和速度很低,想找一种东西替代DOM,但又能有DOM的嵌套结构和属性。因而FaceBook工程师们创造出virtualDOM。本质上virtualDOM就是一个json对象,用来描述真实DOM应有的属性和子集。拥有和DOM同样的嵌套关系造成的virtualDOM树。前端

举个例子:咱们有一段HTMLvue

<div id="wrap">
    <div class="box1" style="margin-left: 10px;padding-top: 10px;"></div>
    <div class="box2">
        <span data-name='box'>this is a box</span>
    </div>
</div>

上述是一段很简单的有嵌套关系的HTML,咱们能够看到里面有几个关键属性,其实只须要记住这几个关键属性,咱们就至关于知道了整段节点。
根据上述HTML,抽象出来的该节点的关键属性。react

var conatiner = {
    tagName: 'div',
    id: 'wrap',
    children: [box1, box2]
};

var box1 = {
    tagName: 'div',
    className: 'box1',
    style: {marginLeft: '10px', paddingTop: '10px'},
    children: []
}

var box2 = {
    tagName: 'div',
    className: 'box2',
    children: [text]
};

var text = {
    tagName: 'span',
    'data-name': 'box', // 自定义属性
    text: 'this is a box'
    children: []
};

上面的HTML里面真正有用的信息仅仅几行代码就能够描述。React作的其实就是反向绘制。git

一个真实节点有不少属性,可是不少属性是绘制DOM相关的(好比offset,scrollTop这种,节点渲染以后添加的跟节点样式相关的属性)。virtualDOM对这些不常见属性暂不考虑(实际上这些绘制DOM的属性都在react-dom中),抽出重要的属性,以及嵌套关系记录下来(高效),放到内存中(迅速),这样减小了不少用不到的属性。 当virtualDOM树生成出来以后,只要按照特意的方法解析(JSX),就会快速的生成出DOM了。
以上大概就是React诞生的缘由和核心原理。github

2、diff算法

另外一个著名的特色就是神秘的diff算法。这个算法也不难,甚至以为并不如宣传的那么牛*还有些失望。可是仍是比较麻烦的。
diff算法主要是用来判断两个virtualDOM树差别的,目的是以最小的代价去更新树。
当特定情境发生须要更改DOM的时候,React并不认为直接操做DOM是最好的选择。他认为不管是简单的DOM操做仍是复杂的DOM操做,都应由改动前的virtualDOM和改动后的virtualDOM计算出来,而后根据计算结果再去渲染DOM。这样至关因而计算出每次操做DOM的最优算法
举个例子 须要移动火材棍使等式成立算法

clipboard.png

图1-移动火材棍使等式成立示意图json

普通状况下你们直接将4个火材棍移到最前,两个火材棍移到中间,这样4-2=2等式成立。
聪明一点的人发现只须要移动中间的两个火材棍到最左,便可使等式成立。这样代价更小。
React通过计算发现:原来只须要移动"="的一个火材棍到"-"便可使等式成立2=4-2这样代价最小。
diff算法就是这样的一套标准化计算流程,其告诉React每次变化如何更改DOM代价最小,或者直接从新渲染性能最优。redux

3、State

React的另外一个创新思惟就是数据为中心。这也是现代前端框架广泛的思想。
如今渲染DOM也不用咱们来管了,操做DOM也不用咱们来管了那咱们来管什么?
咱们须要管理数据,告诉React什么使用,应该有什么样的DOM。
React是根据virtualDOM来渲染DOM的,那virtualDOM是根据什么生成的?答案就是state
React关键点就是state改变,就会从新渲染DOM,这样只须要将影响页面的数据放到state中。设置好什么时候如何触发修改state,剩下的React就会自动完成。数组

4、JSX

JSX能够说也是React的核心部分。它使用XML的标记方式直接去声明界面,组件界面间能够嵌套。
JSX最鲜明的特征就是,script标签中声明text属性为text/babel,这样调用babel解释器。
上面是官方的说法用通俗的话说就是:JSX其实就是一个为了使咱们方便使用React发明的一种转义工具。
包括在下面的例子中,咱们能够看到例子中的语法跟正常使用的语法不一样,就是由于babel。React原始的语法是不支持咱们如今使用组件嵌套的,好比down下React官方推荐的demo,第二个例子中的源代码以下:

clipboard.png

图2-使用JSX语法编写示例

能够看到Counter组件的render方法return出了一个button组件。
若是打开React官方demo的第一个例子,会发现语法彻底不一样。

clipboard.png

图3-使用React语法编写示例

能够看到原始的React语法是不支持组件嵌套的。甚至是不支持return <div><div>的。render方法return的只能是虚拟DOM。

5、React渲染过程研究

React如何将用户输入的代码实现成真实DOM,是接下来要研究的问题。大体过程能够分为首次渲染和再次渲染。

clipboard.png

图4-React渲染机制示意图

上图是整理出来的React渲染机制的流程图,左边的首次渲染的过程,右边是再次渲染的过程。这里主要讲解下该图。

1.首次渲染

咱们在使用React的时候,每每定义不少组件,组件输出的DOM中,还有自定义组件。
在JS最后,使用ReactDOM.render(element, container);将定义好的组到一个容器中。
咱们能够将首次渲染过程分为如下几步:

  1. React首先对咱们定义组件进行解析 解析后的每一个组件的返回结果其实就是一个个virtualDOM 每一个virtualDOM中都会有children属性保存其子节点 这样根节点解析后 会产生一个完整的virtualDOM树。

  2. React.render解析根节点virtualDOM 进而解析整个virtualDOM树(在React1.0以后 React拆分红React和React-dom 如今都使用ReactDOM.render)

  3. React.render将virtualDOM传递给组件工厂 工厂断定virtualDOM具体类别进行具体解析 好比React将virtualDOM分为三类:文本节点 浏览器自带元素和自定义组件 每一个类的virtualDOM都有各自对应的component类进行解析 如上图

  4. 将每一个virtualDOM解析以后 调用各自component类的mountComponent方法 将virtualDOM翻译成真实DOM 并将其事件挂载到Document对象上

  5. 将整个virtualDOM翻译的真实DOM挂载到容器中

  6. 触发mount事件

这样就完成了首次渲染的逻辑,能够看到首次渲染的逻辑仍是比较简单,就是整理出定义的关键属性和嵌套关系成virtualDOM,按照virtualDOM进行绘制真实DOM,输出到挂载点上。
能够看一个简单的例子:

clipboard.png
图5-React首次渲染实例-代码

clipboard.png
图6-React首次渲染实例-显示

在上面的例子中咱们能够看到,定义了一个block和Box。React.createElement的第三个参数就是其子节点数组,box有三个block子节点和一个文本节点。最后将输出的DOM挂载到container上,显示如预期同样。咱们再来看看在此渲染的过程:

2.再次渲染(reRender)

  1. 每次调用setState方法,都会调用该组件receiveComponent方法。

  2. receiveComponent方法修改state而且判断,更改state后DOM是否发生修改,是的话diff算法实现最小更新。

  3. 渲染完成 调用hook函数componentDidUpdate。

这里再次渲染过程很简单,可是是最复杂的过程。每次渲染完成时virtualDOM树会继续保存在内存中, 在更改state等状况下直接使用。 三种不一样类型的节点,有着不一样的更改方法:好比文本节点直接替换 浏览器自带元素使用diff算法复杂计算。
React节点会有一个key属性,该属性就是React进行diff计算的。key上携带者嵌套,索引等相关信息。 diff算法中会递归找出virtualDOM树中的差异,组装成差别对象,添加到更新队列,在合适的时机进行更新。
以上就是React渲染机制的大体过程,至于diff算法这里暂不介绍,下面参考连接有详细介绍。

React优点和劣势

2013年React开源,做为目前较火的现代前端框架它有哪些优势和缺点,也是咱们能够了解。在众多框架中选型的重要参考。
目前较流行的框架有angular、vue等,下面横向做对比分析其优缺点。

1. Angular

Angular是09年google工程师建立的。做为划时代的前端框架,其创新性的使用指令系统和MVVM框架
优势:
丰富的指令系统,强大的指令系统是的开发者能够有不少方便的使用方法供选择;
较完善的MVVM框架,包含模板、路由、双向数据绑定、模块化、服务、过滤器、依赖注入等全部功能;
google去维护,用户数多,社区强大。
缺点:
太过繁杂的指令系统,提升了学习成本。
渲染速度太慢,有人作过测试以下图:

clipboard.png
图中表示不一样框架每秒能渲染的操做数,越长表明性能越好。可见angular基本排在最后。
angular2对比angular1断崖式升级,对开发者形成很高的学习成本。

2. Vue

Vue是近些年最火爆的框架(国内)。尤为在做者尤大加入到阿里后,vue在国内的影响力和推广力更强。
优势:
渲染效率差很少是React的10倍;
结合Angular和React的优势,有模板、有virtualDOM、有过滤器和指令系统。上手简单,十分方便。
缺点:
新生儿。做者16加入阿里,维护和社区方面跟其余两个框架比,不是很强大。
不支持IE8。(??什么是IE8??)

3. React

主角来了。通过几年的发展,你们的实践,React也是愈来愈完善。不断推出的React邪教全家桶(router redux RN等)也是渐渐丰富了React的生态。
优势:
思想新颖,影响了vue等框架;
FaceBook是他亲爹,不少大型项目都在用,完善的维护和强大的社区(国外各类追捧)。
缺点:
新颖的思惟,形成了其须要理解实现过程,上手成本较高;
对动画效果支持不是很好;
不是MV框架,只负责UI绘制须要学习全家桶来实现MV框架。

参考文献:

  1. reactjs源码分析-上篇(首次渲染实现原理)

  2. reactjs源码分析-下篇(更新机制实现原理)

  3. Angular Vue React 渲染实现比较

  4. ARV 渲染实现比较之 Angular

  5. 对比其余框架 - Vue.js

  6. vue,angular,avalon这三种MVVM框架之间有什么优缺点?

相关文章
相关标签/搜索