1. 什么是Virtual DOM?

Virtual DOM(虚拟DOM)是指用JS模拟DOM结构。本质上来讲VD是一个JS对象,并且至少包含三个属性:tag(html标签),props(标签的属性,如class),children(子元素对象)。

<div class="setting-menu">
<ul>
<li>Picture</li>
<li>Sound</li>
<li>Time</li>
</ul>
</div

用JS模拟上面这段DOM结构:

{
tag: 'div',
props: {class: 'setting-menu'},
children: [
{
tag: 'ul',
props: {},
child: [
{
tag: 'li',
props: {},
children:['Picture']
},
{
tag: 'li',
props: {},
children:['Sound']
},
{
tag: 'li',
props: {},
children:['Time']
}
]
}
]
}

2. 为什么需要Virtual DOM?

知其然,知其所以然。我们知道了什么是虚拟DOM之后,还得需要知道为什么需要他?

首先,我们先达成一个共识:"JS操作DOM的代价是昂贵的,会引起回流和重绘,严重影响性能"。

现在有一个需求,上诉DOM结构需要支持修改,增加,删除?

1. 最简单的做法:通过JS操作DOM。该方法的缺点:随这应用的复杂度提升,代码变的难以维护,且性能不好,每次dom操作可能都会引起浏览器的回流和重绘。

2. MVC模式。之后研究出了MVC,MVP模式,但这种模式只是从代码组织的方式来降低维护难度,并没用改变JS操作DOM的本质。

3. MVVM模式,只要在模版中声明视图组件是和什么状态进行绑定的,双向绑定引擎就会在状态

更新的时候自动更新视图,MVVM 可以能很好的降低维护状态以及减少视图的复杂程度。

还有一个非常直观的方法,可以大大降低视图更新的操作。一旦状态发生了变化,就用模版引擎重新渲染整个视图,然后用新的视图更换掉旧的视图。就像上面的表格,当用户点击的时,还是在 JS 里面更新状态,但是页面更新就不用手动操作 DOM 了,直接把整个表格用模版引擎重新渲染一遍,然后设置一下 innerHTML 。那么这个方法会有个很大的问题,会导致 DOM 操作变慢,因为任何的状态变更都要重新构造整个 DOM,性价比很低。对于局部的小视图的更新,这样没有问题(backbone就是这么干的)。但对于大型视图,需要更新页面较多局部视图时,这样的做法就非常不

可取。

使用Jquery模拟:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="container"></div>
<button id="btn-change">change</button> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script type="text/javascript">
var data = [{
name: "张三",
age: 24,
address: "深圳"
}, {
name: "张三",
age: 24,
address: "深圳"
}, {
name: "张三",
age: 24,
address: "深圳"
}]; /**
* 渲染页面
*
*/
function render(data) {
// first step clear container
$('#container').html(''); // 拼接ul
var uldom = document.createElement('ul');
for(var i = 0; i < data.length; i++) {
var lidom = document.createElement('li');
lidom.append(`name: ${data[i].name}, age: ${data[i].age}, address: ${data[i].address}`);
uldom.appendChild(lidom);
} //渲染页面 放到最后 一次渲染
$('#container').append(uldom);
} $('#btn-change').click(function () {
data[1].name = '李四';
data[2].name = '王五'; //修改后重新渲染
render(data);
})
render(data); //初始化页面渲染 </script>
</body>
</html>

  

既然JS操作DOM很慢,而操作JS对象非常快,就可以用 JavaScript 对象表示的树结构来构建一个真正的 DOM 。当状态变更时,重新渲染这个 JavaScript 的对象结构,实现视图的变更,结构根据变更的地方重新渲染。这就是Virtual DOM 算法。

通过VD的比较,我们可以将多个操作合并成一个批量的操作,并且只更新有差异的部分,从而减少dom重排的次数,进而缩短了生成渲染树和绘制所花的时间。

Virtual DOM 系列一:认识虚拟DOM的更多相关文章

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

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

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

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

  3. 原生DOM操作vs框架虚拟DOM比较

    1. 原生 DOM 操作 vs. 通过框架封装操作. 这是一个性能 vs. 可维护性的取舍.框架的意义在于为你掩盖底层的 DOM 操作,让你用更声明式的方式来描述你的目的,从而让你的代码更容易维护.没 ...

  4. React:关于虚拟DOM(Virtual DOM)

    Virtual DOM 是一个模拟 DOM 树的 JavaScript 对象. React 使用 Virtual DOM 来渲染 UI,当组件状态 state 有更改的时候,React 会自动调用组件 ...

  5. 虚拟DOM与DOM diff算法

    虚拟DOM是什么? 一个虚拟DOM(元素)是一个一般的js对象, 准确的说是一个对象树(倒立的) 虚拟DOM保存了真实DOM的层次关系和一些基本属性,与真实DOM一一对应,如果只是更新虚拟DOM, 页 ...

  6. 什么是虚拟DOM?

    (摘抄自一篇文章,觉得这里写得非常不错,所以单独放出来,希望能对大家有帮助.)React为啥这么大?因为它实现了一个虚拟DOM(Virtual DOM).虚拟DOM是干什么的?这就要从浏览器本身讲起 ...

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

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

  8. vue2.0的虚拟DOM渲染

    1.为什么需要虚拟DOM 前面我们从零开始写了一个简单的类Vue框架(文章链接),其中的模板解析和渲染是通过Compile函数来完成的,采用了文档碎片代替了直接对页面中DOM元素的操作,在完成数据的更 ...

  9. 如何编写自己的虚拟DOM

    要构建自己的虚拟DOM,需要知道两件事.你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂--但实际上,虚拟DOM的主要部分只需不到50行代码. 有 ...

  10. 深入理解React虚拟DOM

    一.什么是虚拟DOM 虚拟DOM可以看做一棵模拟了DOM树的JavaScript对象树.比如: var element = { element: 'ul', props: { id:"uli ...

随机推荐

  1. ABP框架连接Mysql数据库

    开始想用Abp框架来搭建公司的新项目,虽然一切还没有定数,但是兵马未动,粮草先行,我先尝试一下整个过程,才能够更好的去争取机会. 此次技术选型:Abp(Asp.Net core mvc)+mysql( ...

  2. spring-security实现的token授权

    在我的用户密码授权文章里介绍了spring-security的工作过程,不了解的同学,可以先看看用户密码授权这篇文章,在 用户密码授权模式里,主要是通过一个登陆页进行授权,然后把授权对象写到sessi ...

  3. unity中ScriptableObject在assetbundle中的加载

    转载请标明出处:http://www.cnblogs.com/zblade/ 以前都是写一些个人的调研博客,从今天开始,也写一些个人在开发中遇到的一些可以分享的趟坑博客,为后续的开发人员提供一些绵薄之 ...

  4. [翻译] 对正在使用EF6x开发人员的一些话

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  5. Hadoop+Hbase分布式集群架构“完全篇”

    本文收录在Linux运维企业架构实战系列 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建,操作完成后整理的个人心得,分享给大家~~~ 1.认识Hadoop和Hbase 1.1 hadoop简 ...

  6. Spring学习(零):我们为什么要学习Spring

    序言 通过使用Spring的IoC容器,可以对这些耦合关系(对Java代码而言)实现一个简单的文本化的操作:即是说通过一个或几个XML文文件,我们就可以方便的对应用对象的耦合关系进行浏览.修改和维护, ...

  7. 《JavaScript高级程序设计》笔记:函数表达式(七)

    递归 function factorial(num){ if(num<=1){ return 1; }else { return num * arguments.callee(num-1); } ...

  8. K3日志定时备份

    K3日志超过5万条以后,每次用户登陆后,系统都会提示日志太多.但是日志又不能随意删除,所以需要做个数据库定时任务,定时把日志转移到备份表. declare @dt datetime;; SELECT ...

  9. 从零开始搭建服务器部署web项目

    前言 该教程旨在完整描述建站过程,会将博主踩过的坑尽量详细的罗列出来.整个建站流程相对较为庞大,因此做了分解,同时适合大家有针对性的查询感兴趣的部分. 一.如何拥有自己的云服务器. 二.域名的购买与解 ...

  10. 微信小程序中通过腾讯地图进行逆地址解析报错message: "请求来源未被授权, 此次请求来源域名:servicewechat.com"

    在小程序中获取定位具体信息时,不要配置腾讯地图中的WebServiceAPI中的域名白名单什么的,域名配置直接在小程序后台中配置(就是这个货https://apis.map.qq.com), 千万千万 ...