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. vi/vim打开文件提示Found a swap file by the name

    问题分析 有一次在远程连接主机时,用vi打开文件my.ini却提示:Found a swap file by the name ".my.ini.swp".百度了下才知道,原来在使 ...

  2. pip 参数

    pip 自带参数 pip --help pip install 自带参数 pip install --help

  3. 新生代内存中为什么要有两个survivor区

    首先是关于新生代中的内存分布的描述: 新生代中的对象都是“朝生夕死”的对象,所以每次gc存活的对象很少,于是在新生代中采用的垃圾回收算法是“复制算法”. 将新生代的内存分为一块较大的Eden区域和两块 ...

  4. 使用em和rem替代px

    rem是指根元素的字体大小,默认情况下html的字体大小为:16px=1rem.而em是相对单位,是基于它的祖先元素计算的. 如果我们不指定html和body的字体大小,要得到12px的rem需要这样 ...

  5. python转换已转义的字符串

    python转换已转义的字符串 有时我们可能会获取得以下这样的字符串: >>> a = '{\\"name\\":\\"michael\\"} ...

  6. win10安装CAD后出现致命错误

    现在很多朋友在使用win10系统了,在win10系统打开cad却提示致命错误,这个时候应该怎么办呢?我们可以打开注册表编辑器然后找到某个注册表把数值改为0就可以解决这个问题了哦,下面就和小编一起来看看 ...

  7. Java GUI 顶级容器JFrame、JDialog

    JFrame的常用构造函数: JFrame() JFrame(String title)   //窗口标题,会显示在左上角窗体图标的后面 JDialog的常用构造函数: JDialog() JDial ...

  8. 【原创】微信公众号与HTML 5混合模式揭秘4——jssdk调用微信扫一扫

    微信公众号与HTML 5混合模式揭秘1——如何部署JSSDK 微信公众号与HTML 5混合模式揭秘2——分享手机相册中照片 微信公众号与HTML 5混合模式揭秘3——JSSDK获取地理位置   在JS ...

  9. Sublime的用法

    一.首先安装插件 1.安装Package Control,这是为了安装其他插件做基础,它可以方便我们下载其他插件 (1).按Ctrl+`调出console(注:避免热键冲突) (2).粘贴以下代码到命 ...

  10. 生鲜o2o配送应用系统,包括Android源码+SSH带后台管理系统

    前台功能划分    我的 登录            账户+密码 注册            订单管理 查看/删除(显示订单详情)                支付(提交订单)           ...