当组件当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. MongoDB复杂查询语句记录

    前段时间做业务监控,用到了MongoDB,有一个查询是把一个含array的list里面查询array中是否存在某一对unique值,不存在的情况下插入一条记录. 类似这样一个表: Biao{ id, ...

  2. Oracle 角色及其权限

    一.简介 Oracle权限分为系统权限和对象权限. 1.系统权限 注意:系统权限不支持级联回收,所以你需要使用sysdba一个个的回收. 2.对象权限 注:对象权限支持级联回收,系统权限不支持级联回收 ...

  3. 我的博客已经迁移到csdn

    博客已经迁移csdnhttp://blog.csdn.net/u013372900 博客园我很喜欢是源于他的可扩展性,可以自己去改,但遗憾的是博客园的速度似乎不是很给力.IT能有今天的 发展是源于无数 ...

  4. 移动端本地 H5 秒开方案探索与实现

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 企业微信移动端项目中有需求要展示数据趋势的可视化图表,经过调研,最终决定以单页面 H5 来完成,对 APP 里的一些使用 H5 实现的功能模 ...

  5. 【卷土重来之C#学习笔记】(三) 类型 存储和变量

    .c#程序是一组类型声明 ※C#程序或DLL的源代码是一组一种或多种类型声明 ※对于可执行程序,类型声明必须有一个包含Main方法类 ※命名空间是一种把相关的类型声明分组并命名的方法.既然程序是一组相 ...

  6. Java学习第二十三天

    1:多线程(理解) (1)多线程:一个应用程序有多条执行路径 进程:正在执行的应用程序 线程:进程的执行单元,执行路径 单线程:一个应用程序只有一条执行路径 多线程:一个应用程序有多条执行路径 多进程 ...

  7. [转]Oracle job procedure 存储过程定时任务

    本文转自:http://www.cnblogs.com/hoojo/p/oracle_procedure_job_interval.html oracle job有定时执行的功能,可以在指定的时间点或 ...

  8. ASP.NET之Request和Response对象

    经过了牛腩新闻公布系统和html的学习对B/S开发的流程有了些理解.前面尽管用到了非常多知识.但对制作网页仅仅能说知其然.当学到asp.net视频中的解说才干够说開始知其所以然了. 今天来说说clie ...

  9. .net使用redis入门笔记

    1.学习blog:http://www.cnblogs.com/yangecnu/p/Introduct-Redis-in-DotNET.html 2.redis官网:http://redis.io/ ...

  10. Hadoop-HA(高可用)集群搭建

    Hadoop-HA集群搭建 一.基础准备工作 1.准备好5台Linux系统虚拟服务器或物理服务器 我这里演示采用虚拟服务器搭建Hadoop-HA集群,各自功能分配如下: NameNode节点:vt-s ...