https://github.com/livoras/blog/issues/13

这里简单记录一些要点和理解:

  一个dom元素中有许多属性,操作dom是很耗资源的,而操作自定义的js对象是很高效。所以在操作dom之间多加一层“虚拟dom”,建立虚拟dom与dom的关联,把直接操作dom转换为操作虚拟dom,然后把最终的虚拟dom关联到dom上,关联的方式是把差异应用到dom上。

  一个js对象来描述一个dom,只需要tagName、props以及children即可。

一个虚拟dom应用,有如下初始化过程

  1. 通过js(如react的jsx)确定好虚拟dom
  2. 根据虚拟dom生成实际的dom树,写到body中  

在js中对虚拟dom进行操作,每次操作会生成一颗新的虚拟dom树,虚拟dom的新树和旧树进行对比,找出差异,然后这些差异会被应用到实际的dom上,完成界面的变更。

对比方式:

  同层次节点对比,深度优先。

差异的类型以及处理方式

  1. 标签名变更,则整个节点统一进行替换,里面的子节点也跟着替换。
  2. 标签的属性变更,把变更的属性应用上去。
  3. 文本节点内容变更,直接替换即可。
  4. 子元素个体的增加、删除、移动。

如何检测子元素个体的变更?

  为每个个体都加上一个标识符key,在当前兄弟节点中这个key要唯一,这样才能在当前的所有children中唯一标识。标识完成后,问题就可以转化为字符串的对比问题了,这里对比只能得出列表的差异(增加删除移动等)。接着继续进行相同key的节点的对比,到这里可见差异的对比是递归的。进行子元素个体的标识,有利于dom的复用,如果不指定,算法会认为两个子元素列表完全不一样,会全部重新渲染,这就很耗费性能了。

“如果元素没有重排,使用数组的索引作为key效果不错”。如何理解这句话呢?

  没重排的意思是,结构体的展示次序不发生变化,而仅仅是结构体中少量属性发生变更。在这种情况下,两个列表元素依次一一对应,找出差异,然后把这些差异按次序应用到列表dom上。如果元素有重排,而且使用了索引作为key,两个列表中相同索引的结构体会完全不同,这样一进行对比,可能会得出一大堆的差异,再将这些差异应用上去可能会比较慢,我感觉其实这些说的都只是相对而已。

如何把差异应用(patch)到实际dom上?

  最开始初始化的时候,根据虚拟dom生成实际的dom,两者的结构层次是一样的,而差异是通过对虚拟dom深度优先对比出来的,应用当然是对实际dom进行深度优先,然后把差异应用上去。

  

虚拟dom和diff算法的更多相关文章

  1. 【React 7/100 】 虚拟DOM和Diff算法

    虚拟DOM和Diff算法 React更新视图的思想是:只要state变化就重新渲染视图 特点:思路非常清晰 问题:组件中只有一个DOM元素需要更新时,也得把整个组件的内容重新渲染吗? 不是这样的 理想 ...

  2. 虚拟DOM与diff算法

    虚拟DOM与diff算法 虚拟DOM 在DOM操作中哪怕我们的数据,发生了一丢丢的变化,也会被强制重建整预DOM树.这么做,涉及到很多元素的重绘和重排,导致性能浪费严重 只要实现按需更新页面上的元素即 ...

  3. vue虚拟dom和diff算法

    vue的虚拟dom和diff算法 1.虚拟dom 虚拟dom,我的理解就是通过js对象的方式来具体化每一个节点,把dom树上面的每个节点都变为对象里的一个元素,元素的子元素变为子节点,节点上面的cla ...

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

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

  5. 虚拟dom与diff算法 分析

    好文集合: 深入浅出React(四):虚拟DOM Diff算法解析 全面理解虚拟DOM,实现虚拟DOM

  6. react中虚拟dom的diff算法

    .state 数据 .jsx模板 .生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM) ['div', {id:'abc'}, ['span', {}, 'hello world']] ...

  7. vue之虚拟DOM、diff算法

    一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...

  8. 【前端知识体系-JS相关】虚拟DOM和Diff算法

    1.介绍一下vdom? virtual dom, 虚拟DOM 使用JS来模拟DOM结构 DOM变化的对比,放在JS层来做(图灵完备语言),提高效率 DOM操作非常昂贵(消耗性能) 2.Snabbdom ...

  9. 【React自制全家桶】二、分析React的虚拟DOM和Diff算法

    一.React如何更新DOM内容: 1.  获取state 数据 2.  获取JSX模版 3.  通过数据 +模版结合,生成真实的DOM, 来显示,以下行代码为例(简称代码1) <div id= ...

  10. 探究虚拟dom与diff算法

    一.虚拟DOM (1)什么是虚拟DOM? vdom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息,如下图:   可见左边的DOM结构,不论是标签名 ...

随机推荐

  1. iOS 利用模态视图实现带黑色蒙版的底部弹窗

    本demo仅适用于iOS8及以上系统. 本文将使用autolayout+storyboard来实现弹窗 第一步.storyboard创建界面 1.打开storyboard 拖一个UIViewcontr ...

  2. 基于java开发的在线题库系统tamguo

    简介 探果网(简称tamguo)是基于java开发的在线题库系统,包括 在线访问 后台运营 会员中心 书籍中心 管理员账号:system 密码:123456 因为线上数据和测试数据没有做到隔离,作者已 ...

  3. Python 数字模块

    Python中的数字模块 math模块 random模块 Decimal模块 - 没有损失的小数 Fraction模块 - 可以计算分数

  4. asp.net多文件上传

    文件上传简单实现是非常容易的,但是想要更高的要求,比如通过ajax上传文件.一次上传多个文件.文件比较大等等,这里面的坑就不是很容易填(对于新手来说).因此在这里我准备通过ajax实现多文件上传.在开 ...

  5. python shutil

    #! /usr/bin/env python# -*- coding:utf-8 -*-# shutil 高级的文件.文件夹.压缩包处理模块import shutil #1.copyfileobj(源 ...

  6. python 全局变量 局部变量

    ##全局变量,局部变量#在函数内部可以调用全局变量,不能随意改变全局变量#若要在函数内部改变全局变量,需用关键字global #代码中全局变量都大写,局部变量都小写(非必须,一种规范) P = &qu ...

  7. [译]Understanding ECMAScript 6 说明

    说明 JavaScript核心语言功能定义在ECMA-262中,此标准定义的语言是ECMAScript,浏览器中的JavaScript和Node.js环境是它的超级.当浏览器与Node.js想要通过额 ...

  8. httpd.exe占用100%CPU

    客户VPShttpd.exe进程占用100%CPU百度搜了下,很多文章: 在网上也没有能够直接找到比较好的解决方法,后来在一个帖子上看到说,有可能是apache与其他的软件冲突了(参考http://t ...

  9. matlab实现gabor滤波器的几种方式

    转自:http://blog.csdn.net/watkinsong/article/details/7882443 方式一: function result = gaborKernel2d( lam ...

  10. LOJ#111. 后缀排序(二分 hash)

    题意 给出一个字符串,求出排名为$i$个字符串在原串中的开始位置 Sol 纪念一下这伟大的时刻qwq. 我用二分+hash把这题水过去了qwq. #include<cstdio> #inc ...