当组件当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格式化字符 %s %d %f

    Python格式化字符 %s %d %f 原文:http://blog.csdn.net/huangfu77/article/details/54807835 格式 描述%% 百分号标记 #就是输出一 ...

  2. Python 中的反射和自省

    本文主要介绍Python中的反射和自省,以及该机制的简单应用 熟悉Java的程序员,一定经常和Class.forName打交道.即使不是经常亲自调用这个方法,但是在很多框架中(spring,eclip ...

  3. 案例42-使用ajax获取crm中的客户列表

    1webcontent部分 1 修改menu.jsp代码 2 jsp/customer/list.jsp代码 <%@ page language="java" content ...

  4. opensuse install oracle 11gR2 Error in invoking target 'agent nmhs' of makefile '../ins_emagent.mk'

    转自 http://blog.csdn.net/ly5156/article/details/6647563 遭遇Error in invoking target 'agent nmhs' of ma ...

  5. Mysql中各种与字符编码集(character_set)有关的变量含义

    mysql涉及到各种字符集,在此做一个总结. 字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思.mysql的环境变量分为两种:session和global.session ...

  6. topN问题

    topN问题:给出一个数组,找出前N个最大的元素. topN问题可以用分治法解决,这个问题与快速排序类似,快速排序是用一个数对数组进行划分,topN问题则不需完成排序,只需划分出前n个最大的数字即可. ...

  7. FZU 2214 ——Knapsack problem——————【01背包的超大背包】

    2214 Knapsack problem Accept: 6    Submit: 9Time Limit: 3000 mSec    Memory Limit : 32768 KB  Proble ...

  8. ZOJ 1610——Count the Colors——————【线段树区间替换、求不同颜色区间段数】

    Count the Colors Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Subm ...

  9. Visual Studio 安装OpenCV及问题总结

    1.VS安装OpenCV基本步骤 1)安装Visual Studio 下载网址https://opencv.org/releases.html# 2)安装OpenCV 下载网址https://www. ...

  10. bzoj 5302: [Haoi2018]奇怪的背包

    Description Solution 首先 \(v_1,v_2,v_3...v_n,P\) 能够构成的最小数是 \(gcd(P,v_1,v_2,v_3...v_n)\) 然后 \(gcd(P,v_ ...