3

虚拟DOM - 不见水星记

 1 year ago
source link: https://www.cnblogs.com/P1Kaj1uu/p/17021262.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、对虚拟DOM的理解

虚拟DOM就是用来描述真实DOM的javaScript对象,可以将多次修改的DOM一次性渲染到页面上,减少页面的重排重绘,提高渲染性能

  • 虚拟DOM就是用来描述真实DOM的javaScript对象,可以将多次修改的DOM一次性渲染到页面上,减少页面的重排重绘,提高渲染性能。 在代码渲染到页面之前,vue会把代码转换成一个对象(虚拟 DOM)。在每次数据发生变化前,虚拟DOM都会缓存一份,变化之时,现在的虚拟DOM会与缓存的虚拟DOM进行比较。在vue内部封装了diff算法,通过这个算法来进行比较,渲染时修改改变的变化,原先没有发生改变的通过原先的数据进行渲染。

二、虚拟DOM的解析过程

  1. 首先对将要插入到文档中的 DOM 树结构进行分析,使用 js 对象将其表示出来并将这个 js 对象树给保存下来,最后再将 DOM 片段插入到文档中。
  2. 当页面的状态发生改变,需要对页面的 DOM 的结构进行调整的时候,首先根据变更的状态,重新构建起一棵对象树,然后将这棵新的对象树和旧的对象树进行比较,记录下两棵树的的差异。
  3. 最后将记录的有差异的地方应用到真正的 DOM 树中去,这样视图就更新了。

三、使用虚拟DOM的原因

  • 跨平台
    • Virtual DOM本质上是JavaScript的对象,它可以很方便的跨平台操作,比如服务端渲染、uniapp等。
  • 提高渲染性能
    • 页面渲染的流程
      • 解析HTML -> 生成DOM -> 生成 CSSOM -> Layout -> Paint -> Compiler
    • 对比修改DOM时真实DOM操作和虚拟DOM的过程
      • 真实DOM∶ 生成HTML字符串+重建所有的DOM元素
      • 虚拟DOM∶ 生成vNode+ DOMDiff+必要的dom更新(vNODE:虚拟节点;vDOM:虚拟DOM,虚拟DOM是由多个虚拟节点构成的)

四、虚拟DOM是否真的比真实DOM性能好

  • 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。
  • 正如它能保证性能下限,在真实DOM操作的时候进行针对性的优化时,还是更快的。

五、DIFF算法的原理

Diff 的对象是虚拟DOM(virtual dom),更新真实 DOM 是 Diff 算法的结果

  • 首先,对比节点本身,判断是否为同一节点,如果不为相同节点,则删除该节点重新创建节点进行替换。
  • 如果为相同节点,进行patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的没有子节点,将旧的子节点移除)。
  • 比较如果都有子节点,则进行updateChildren,判断如何对这些新老节点的子节点进行操作(diff核心)。
  • 匹配时,找到相同的子节点,递归比较子节点。
  • 更新差异,复用节点。

六、Vue中key的作用

  • 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。因此可以通过使用 key 来唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识一个独立的元素。
  • 第二种情况是 v-for 中使用 key。用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM。
  • 总结
    • vue为了更高效的渲染元素,会尽可能的复用元素,而非从头渲染,key可以为节点打标记,而非简单的复用节点。当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则。
      • 旧虚拟DOM中找到了与新虚拟DOM相同的key
        • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
        • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
      • 旧虚拟DOM中未找到与新虚拟DOM相同的key
        • 创建新的真实DOM,随后渲染到到页面

七、不建议用index作为key的原因

后续操作不破坏原来数据顺序的话,使用index作为key也没有任何问题

  • 若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
  • 如果逆序添加、逆序删除等破坏顺序的操作且结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题。

八、真实DOM

2990843-20230103101454907-1240674860.png

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK