当组件当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. scala 中格式化字符常用的格式符

    val name="Fred" val age=20 val weight=150.00 val dd="%s's age is %d,weighs %.2f" ...

  2. VIRTIO概述和基本原理

    http://smilejay.com/2012/11/virtio-overview/ (KVM连载)5.1.1 VIRTIO概述和基本原理(KVM半虚拟化驱动) 11/15/2012MASTER  ...

  3. linux命令行下的操作的快捷键

    历史相关命令 命令                   含义!!                      执行上一条命令!num                 执行历史命令中的第num条命令!-n ...

  4. day07 - Python - 面向对象进阶

    本节内容: 面向对象高级语法部分异常处理异常处理异常处理 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 作业:开发一个支持多用户在线的FTP程序 面向对象高级语法部分 1 ...

  5. LaTex 2

    LaTex 入门 此时是否安装成功 如果安装成功了LaTeX, 那么在计算机上会多出来LaTeX的编译器, LaTex Live 安装包在计算机上安装了多个不同的编译器, 有latex, xelate ...

  6. 修改ThinkPHP的验证码类

    今天用ThinkPHP重新开发一个系统,用到了ThinkPHP的验证码类,由于我希望验证码别太复杂,希望验证码里边只有数字,却发现该Verify类并未提供设置验证码中使用的字符的配置的方法,于是查看源 ...

  7. 【tomcat】关于tomcat的使用:将tomcat加入系统服务列表

    一.下载TOMCAT 选择合适的版本进行下载: http://tomcat.apache.org/ 解压zip文件得到tomcat目录: 二.添加CATALINA_HOME到环境变量 service. ...

  8. 从零开始的全栈工程师——MySQL数据库( Dos命令 ) ( phpstudy )

    MySQL是一个关系型数据库,存在表的概念.结构,数据库可以存放多张表,每个表里可以存放多个字段,每个字段可以存放多个记录. phpstudy使用终端打开数据库的命令行 密码: root 数据库 查看 ...

  9. 使用canvas及js简单生成验证码方法

    在很多时候都需要用到验证码,前端验证码需要知道Html5中的canvas知识点.验证码生成步骤是:1.生成一张画布canvas 2.生成随机数验证码  3.在画布中生成干扰线  4.把验证码文本填充到 ...

  10. Mac系统在finder拦显示当前所浏览的文件路径的方法

    我们在使用MAC时,Finder栏默认只显示当前浏览的文件夹名称,而没有显示访问路径,这个问题该怎么解决呢? 编辑node的时候需要路径,亲测有效啦~可以试下! 操作步骤: 打开“终端”(应用程序-& ...