当组件当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. python学习11-类的成员(转载)

    一.变量 1.实例变量(又叫字段.属性) 创建对象时给对象赋值 形式: self.xxx = xxx 访问: 对象名.xxx     只能由对象访问 class Person: def __init_ ...

  2. 安装Samba服务让宿主机和虚拟机共享文件

    安装 samba 服务器之后,很方便的实现 Windows 和 Linux 进行通信. 安装步骤: 1 .在 Ubuntu 系统下面安装 samba 服务: $ sudo apt-get instal ...

  3. (转)linux下进程的进程最大数、最大线程数、进程打开的文件数和ulimit命令修改硬件资源限制

    ulimit命令查看和更改系统限制 ulimit命令详解 ulimit用于shell启动进程所占用的资源,可以用来设置系统的限制 语法格式 ulimit [-acdfHlmnpsStvw] [size ...

  4. 第三章:ionic环境搭建之windows篇

    下面是在windows操作系统上面安装ionic的步骤,已经在Windows 10/ 7/ XP下面通过验证. 安装JDK 1.1 下载(http://www.oracle.com/technetwo ...

  5. java中的各种修饰符作用范围

    访问修饰符: private 缺省 protected public 作用范围: 访问修饰符\作用范围 所在类 同一包内其他类 其他包内子类 其他包内非子类 private 可以访问 不可以 不可以 ...

  6. 遇见phpDesigner我笑了 PHP开发利器

    phpDesigner实在太好用了 相信许多PHP同胞谈到PHP开发工具的时候,都会想到Zend Studio.Eclipse等开发工具,这些工具的确非常的强大强悍,但复杂的配置满屏幕的英文并不适合所 ...

  7. thinkphp执行流程

    1. 入口文件index.php 用户对url的访问首先被定位到http://<serverIp>/<appName>/index.php, 这里的入口文件index.php做 ...

  8. js Base64与字符串互转

    1.base64加密 在页面中引入base64.js文件,调用方法为: <!DOCTYPE HTML> <html> <head> <meta charset ...

  9. winform代码生成器(二)

    代码下载 地址 http://pan.baidu.com/s/1nuZjyat 接着说 上文继续说,这次我们要生成主从表. 此方用到了第三方的 控件 DevExpress 的Gridview .大家可 ...

  10. 【MSDN】 SqlServer DBCC解析

    汇总学习下SqlServer的DBCC指令. DBCC:Transact-SQL 编程语言提供 DBCC 语句以作为 SQL Server 的数据库控制台命令. 数据库控制台命令语句可分为以下类别. ...