一、概念
React 是一个用于构建用户界面的JavaScript库
React可以构建高效 快速的用户界面 它是一个轻量级库 因此很受欢迎
它遵循组件设计模式 声明式编程范式和函数式编程概念 以使前端应用程序更高效
它使用虚拟DOM来有效地操作DOM 并且它遵循从高阶组件到低阶组件的单向数据流
React有两个重要知识点:虚拟DOM和Diff算法
它们可以说是React的核心内容
二、核心
虚拟DOM(Virtual Document Object Model)
DOM是浏览器中的概念 即 用JS对象来表示页面中的元素 提供操作DOM对象的API
而虚拟DOM是框架中的概念 框架用JS对象来模拟页面中的DOM和DOM嵌套
其主要目的是实现页面中的DOM元素的高效更新
例:一个表格 当其中一小部分数据发生改变时 没必要全部重新渲染
但若使用模板引擎的话 会全部重新渲染也仅仅将数据渲染到页面上 会产生性能上的问题
若要实现最优的性能 需要按需渲染页面 只重新渲染更新部分的数据 尽量减少DOM操作以提高性能
若要实现页面的按需更新…
网页呈现的过程:
1、浏览器请求服务器 获取页面的HTML代码
2、浏览器在内存中解析DOM结构 并在浏览器内存中渲染出一棵DOM树
3、浏览器将DOM树呈现在页面上
假设内存中有两棵DOM树:其中一棵DOM树是旧的 另一棵DOM树是最新的
当需要按需更新的时候 将两棵DOM数中的每一条数据进行对比
若数据不一致 则代表需要更新
若数据一致 则不更新了
那么问题来了:如何获取新旧两棵DOM树 从而实现对比?
在浏览器中并没有提供获取DOM树的API(只能获取元素)
因此无法获取浏览器内存中的DOM树
但是可以手动模拟出DOM树
那么 如何模拟DOM树?
比如 要模拟:
<div id="mydiv" class="myclass">
我叫陈涛
<p>来自浙江</p>
</div>
可以用JS实现:
var div={
tagName:"div",
attrs:{
id:"mydiv",
class:"myclass"
},
childrens:[
"我叫陈涛",
{
tagName:"p",
attrs:{},
childrens:[
"来自浙江"
]
}
]
}
手动模拟的这两棵新旧的DOM树 就是React中 虚拟DOM的概念
究其本质 简单来说 就是用JS对象的形式来模拟页面的DOM的嵌套关系
而其目的也很简单 就是为了实现页面元素的高效更新
Diff算法(Different)
只有对新旧两棵虚拟DOM树进行对比后才能进行高效更新
而高效的对比也是至关重要的
React使用了Diff算法(Different)
Diff算法分成三个类型:
- tree diff
- component diff
- element diff
其中 tree diff即为新旧两棵DOM树逐层对比的过程
当整棵DOM树逐层对比完毕 即代表所有需要按需更新的元素必然找到
一个页面是由很多组件组成的 而每个组件之间也需要进行对比
DOM树的每一层可能有很多组件 它们也需要进行对比
若对比前后组件的类型相同 则暂时认为此组件无需更新
若对比前后组件的类型不同 则移除旧组件 创建新组建并追加到页面上
这就是component diff
在判断完组件之后 并不能保证组件内的每个元素都相同
因此 还需要对组件中的每个元素进行对比 这就是element diff
在经过这三种类型的对比之后 即可保证页面是完全相同的了
三、总结
虚拟DOM提供了新旧两棵DOM树 而diff算法提供了最优的比对方案
这就是React的核心