React/虚拟DOM
在说虚拟dom之前,先来一个引子,从输入url到展现出整个页面都有哪些过程?
1、输入网址
2、dns解析
3、建立tcp连接
4、客户端发送htpp请求
5、服务器处理请求
6、服务器响应请求
7、浏览器展示html
8、浏览器发送请求获取其他在html中的资源。
其中浏览器展示html经过了:构建dom树,解析css构建cssom树,dom与cssom结合成为renderobject树,然后将renderobject树渲染成页面(布局->重绘),这个过程是由渲染引擎做的,javascript引擎与渲染引擎是独立的,因为js可以操作dom,所以渲染引擎会暴露给js引擎一些接口来操作dom元素,这个通信过程的耗费是比较大的,所以在性能优化中会有一条:js尽量少操作dom元素,而虚拟dom则是为了解决这一问题而出现。
当你用传统的源生api或jquery去操作dom时,浏览器会从构建dom树开始从头到尾执行一遍流程。比如当你在一次操作时,需要更新10个dom节点,理想状态是一次性构建完dom树,再执行后续操作。但浏览器没这么智能,收到第一个更新dom请求后,并不知道后续还有9次更新操作,因此会马上执行流程,最终执行10次流程。显然例如计算dom节点的坐标值等都是白白浪费性能,可能这次计算完,紧接着的下一个dom更新请求,这个节点的坐标值就变了,前面的一次计算是无用功。
虚拟dom就是为了解决这个浏览器性能问题而被设计出来的。例如前面的例子,假如一次操作中有10次更新dom的动作,虚拟dom不会立即操作dom,而是将这10次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attach到dom树上,通知浏览器去执行绘制工作,这样可以避免大量的无谓的计算量。
什么是虚拟dom?
virtual dom 是一种编程概念。在这个概念里, ui 以一种理想化的,或者说“虚拟的”表现形式被保存于内存中,并通过如 reactdom 等类库使之与“真实的” dom 同步。这一过程叫做。
在某一时间节点调用 react 的 render()
方法,会创建一棵由 react 元素组成的树。在下一次 state 或 props 更新时,相同的 render()
方法会返回一棵不同的树。react 需要基于这两棵树之间的差别来判断如何有效率的更新 ui 以保证当前 ui 与最新的树保持同步。(diffing算法)
这种方式赋予了 react 声明式的 api:您告诉 react 希望让 ui 是什么状态,react 就确保 dom 匹配该状态。这使您可以从属性操作、事件处理和手动 dom 更新这些在构建应用程序时必要的操作中解放出来。
如何创建虚拟dom
jsx就是在创建虚拟dom,jsx就是react.createelement(component, props, ...children)的语法糖
<mybutton color="blue" shadowsize={2}>
click me
</mybutton>
会被babel转译成
react.createelement(
mybutton,
{color: 'blue', shadowsize: 2},
'click me'
)
react.createelement()
会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
classname: 'greeting',
children: 'hello, world!'
}
};
也就是=》react元素
reactdom.render 把虚拟dom转成真实dom,并且挂载