当组件当state和props发生变化当时候,组件当render函数就会重新执行,组件就会被重新渲染,react中实现这种重新渲染,他的性能是非常高的,因为他引入了一个虚拟Dom的概念,那么什么是虚拟的Dom,为什么虚拟Dom带来了变革性当改变
当state发生变化,render函数会重新执行,重新的去渲染一次页面。假设没有react,我们自己要实现这个功能,那应该怎么去实现呢?我们来理个思路
、state 数据
、jsx模板
、把数据 + 模板相结合,生成真实的dom,来显示
、state 发生改变
、数据 + 模板 结合,生成真实的dom,替换原始的dom
这么做,有一个致命的缺陷,是什么呢?
第一次生成了一个完整的dom片段
第二次生成了一个完整的dom片段
第二次的dom替换第一次的dom,非常耗性能。当我们inputvalue发生变化的时候,其实页面上只有input这块dom发生变化,如果是这种做法,虽然是input的数据发生变化,但是我需要整个dom区块重新生成一次,替换掉原始的dom情况,这样的话,生成一个完整的dom片段很耗性能,替换掉一个完整的dom片段,也很耗性能。那我们改良一下
、state 数据
、jsx模板
、把数据 + 模板相结合,生成真实的dom,来显示
、state 发生改变
、数据 + 模板 结合,生成真实的dom,并不直接替换原始的dom
、新的dom(DocumentFragment) 和 原始的dom做比对,找差异
、找出input框发生了变化
、只用新的dom中的input元素,替换掉老的dom中的input元素
这样的话,是有一定的性能提升的。当新的dom替换掉老的dom的时候,涉及到dom替换的操作或者dom比对的操作,实际上是比较耗性能的,所以替换原始的dom耗费了大量的性能。新的做法是什么呢,不替换老的dom,是拿新的dom和原始的dom做对比,只需要更改那一块局部的元素,这样dom替换内容变少了,所以这块性能得以提升,虽然提升了dom替换的性能,但是他又损耗了一部分性能,损耗的性能是哪里呢,损耗的是新的dom要和原有的dom做比对,这样节约了一些性能,又消耗了一些性能,其实在性能的提升上,并不是特别明显。于是react提出了虚拟dom的方案
、state 数据
、jsx模板
、把数据 + 模板相结合,生成真实的dom,来显示
  <div id='abc'><span>hello world</span></div>
、生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM)
  ['div', {id:'abc'}, ['span', {}, 'hello world']]
  通过这样的一个js对象,我们就可以表述上面的dom结构了
、state发生变化
、数据+模板生成新的虚拟dom(极大的提升了性能)
  ['div', {id:'abc'}, ['span', {}, 'bye bye']]
、比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(极大的提升了性能)
、直接操作DOM,改变span中的内容
这种方案相对于上面的方案有什么样的好处,第4步看上去要去另外生成一个虚拟dom,好像还消耗了性能,确实是这样,是有一点性能损耗,用js生成一个js对象,他的代价是非常小的。但是用js生成一个dom元素,他的代价极高,为什么呢?底层的原理是,js生成dom会调用webapplication级别的一个api。这种级别的api性能损耗是比较大的。
旧的方案是数据 + 模板 结合,生成真实的dom,而在新的方案里面不是这样的,是数据+模板生成新的虚拟dom,这一步就极大的提升了性能。
旧的方式是新的dom(DocumentFragment) 和 原始的dom做比对。也就是dom层面的做对比,只要是dom层面的对比,他就是很耗性能,新的方式是比较原始虚拟DOM和新的虚拟DOM的区别,两个js对象的比对是非常不消耗性能的
所以虚拟dom是减少了真实dom的创建以及真实dom的对比,取而代之,我创建的都是js对象,对比的也是js对象,用这种方式提升了性能
 
 
为了方便理解,上面写成先生成真实的dom,再生成虚拟dom,实际上这是反过来的,这点要重新的认识一下
、state 数据
、jsx模板
、生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM)
['div', {id:'abc'}, ['span', {}, 'hello world']]
通过这样的一个js对象,我们就可以表述上面的dom结构了
、用虚拟dom的结构,生成真实的dom,来显示
<div id='abc'><span>hello world</span></div>
、state发生变化
、新的虚拟dom(极大的提升了性能)
['div', {id:'abc'}, ['span', {}, 'bye bye']]
、比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(极大的提升了性能)
、直接操作DOM,改变span中的内容
讲到这里,之前大家会认为jsx就是页面上的dom,但实际上理解原理之后,就知道,他就是一个模板,之后会把这个模板跟state或者props做结合,结合完成之后,有个虚拟dom,有了虚拟dom之后,再生成真实dom。那么jsx的代码和真实的dom有什么样的关系呢?首先,jsx先变成了虚拟dom。也就是js对象。然后再被转化成真实的dom。那么jsx怎么变成js对象呢,js对象you怎么变成真实的dom。
比如 return(<div>item</div>),react底层其实会把jsx语法通过createElement变成js对象,然后再转化真实的dom,return React.createElement('div',{},'item')。这两种效果是一摸一样的。React.createElement是更底层的一个东西,实际上会有一个js对象的东西传递给createElement,那么这个方法实际拿到这个对象之后,直接变成了虚拟dom,然后渲染成真实的dom。所以是
jsx -> createElement -> 虚拟dom(js对象)-> 真实的dom
所以没有jsx,也可以去写页面,但是这样会比较复杂,比如return(<div><span></span></div>)需要写成return React.createElement('div',{},React.createElement('span',{},'item'))
所以jsx不是真实的dom,没有这种语法,完全可以通过createElement实现jsx的功能。jsx之所以存在,是使代码写的方便,简洁。Vue里面也有一个虚拟dom,跟这个也是类似的。
那么虚拟dom带来什么样的好处,只有页面需要渲染的时候,才生成真实的dom。
第一个性能提升了。dom的比对变成了js对象的比对
第二个它使得跨端应用得以实现。大家应该听说过React Native,我们可以通过React语法写原生的应用,这个得益于虚拟dom的存在,假设没有虚拟dom,一开始就是渲染真实的dom,渲染dom在浏览器上是没有问题的,可是在移动端的原生应用里面,比如安卓或ios机器上的代码的时候,它里面是不存在dom这个概念的,所以没有虚拟dom,在原生的app里面根本无法被使用,所以代码只能在浏览器里面,但是有了虚拟dom就不一样了,js对象可以在浏览器里面被识别,同时也可以在原生应用里面被识别,在浏览器里面生成真实的dom,那么在原生应用里面可以不让他生成真实的dom,而是生成原生的组件,这样state,jsx都可以被复用,因为生成的虚拟dom,在哪里都可以运行。这使得react可以开发网页,也可以开发原生应用。

React中的虚拟DOM的更多相关文章

  1. 深入理解react中的虚拟DOM、diff算法

    文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么?   ...

  2. 谈谈Vue/React中的虚拟DOM(vDOM)与Key值

    谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...

  3. 简谈react中的虚拟DOM

    相信你在看到此篇前也翻阅大量的对DOM的文章讲解和介绍 react中的虚拟DOM 此篇我尽量说人话(大白话),不然想必你在看到别的大神的文章早就懂了. 不说废话了,上干货. 1.首先简单对Html中的 ...

  4. 1.React中的虚拟DOM

    1.state 数据 2.JSX模板 3.数据+ 模板 结合,生成真实的DOM,来显示 4.state发生改变 5.数据 + 模板 结合,生成真实的DOM,替换原始的DOM 缺陷: 第一次生成了一个完 ...

  5. [react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?

    壹 ❀ 引 虚拟DOM(Virtual DOM)在前端领域也算是老生常谈的话题了,若你了解过vue或者react一定避不开这个话题,因此虚拟DOM也算是面试中常问的一个点,那么通过本文,你将了解到如下 ...

  6. vue中的虚拟DOM树

    什么是虚拟DOM树?(Virtual DOM)   虚拟DOM树其实就是一个普通的js对象,它是用来描述一段HTML片段的    01    当页面渲染的时候Vue会创建一颗虚拟DOM树 02    ...

  7. 【Web技术】401- 在 React 中使用 Shadow DOM

    本文作者:houfeng 1. Shadow DOM 是什么 Shadow DOM 是什么?我们先来打开 Chrome 的 DevTool,并在 'Settings -> Preferences ...

  8. react 什么是虚拟DOM?深入了解虚拟DOM

    底层的理论基础 一. 原始生成步骤 1.state 数据 2.jsx 模版 3.数据 + 模板 结合,生成真实的DOM,来显示 4.state 发生改变了 5.数据 + 模板 结合,生成真实的DOM, ...

  9. 详解Vue中的虚拟DOM

    摘要: 什么是虚拟DOM? 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 Vue.js 2.0引入Virtual DOM,比Vue.js 1.0的初始渲染速度提升了2-4倍,并 ...

随机推荐

  1. linux 密码复杂度设置

    /etc/login.defs文件,里面几个选项 PASS_MAX_DAYS 90 #密码最长过期天数 PASS_MIN_DAYS 80 #密码最小过期天数 PASS_MIN_LEN 10 #密码最小 ...

  2. SpringBoot---开发的热部署

    1.模板的热部署 在SpringBoot中,模板引擎的页面默认是开启缓存的: 如果修改了页面的内容,则刷新不到修改后的页面: 可以在application.properties中关闭模板引擎的缓存: ...

  3. oracle sql命令

    set time on; 设置时间 alter table flashback_test enable row movement; 开启行移 select * from flashback_test ...

  4. tgz 文件解压

    使用命令:tar zxvf ×××.tgz 即可进行解压 留作备忘

  5. org.hibernate.QueryException: duplicate alias: r hibernate别名重复问题解决

    今天做项目的过程中发现,多表查询的时候如果使用hibernate的DetachedCriteria离线查询方式的时候, 在多表关联的时候我们需要使用别名的方式去实现. 但是代码运行的过程中抛出了下面的 ...

  6. java io 学习笔记(三) 字符流读写

    1.字符流读取 字符流读取的所有类都是从Reader这个超类继承的,都是用于读取字符的,这些类分别是InputSteamReader(从字符流读取).FileReader(继承与InputStream ...

  7. jQuery中的事件——《锋利的JQuery》

    虽然利用原生的JavaScript事件能完成一些交互,但jQuery增加并扩展了基本的事件处理机制.jQuery不仅提供了更加优雅的事件处理语法,而且极大地增强了事件处理能力. 1.加载DOM 在Ja ...

  8. jqGrid 将行的字变成超连接

    今天在项目中碰到要将jqGrid中的行做成超连接,请看代码步骤: name: , align: "left", formatter: function (cellValue, op ...

  9. vue分页

    1.依赖文件 <link href="/css/index.css" rel="stylesheet" type="text/css" ...

  10. 01.里氏准换与using关键字

    using关键字有什么用?什么是IDisposable? using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposiable的类在using中创建,using结束后 ...