zoukankan      html  css  js  c++  java
  • 虚拟DOM(Virtual DOM)

    什么是Virtual DOM?

    Virtual DOM是对DOM的抽象,本质上是JavaScript对象(也就是通过JavaScript语言来描述一段HTML代码),这个对象就是更加轻量级的对DOM的描述.

    虚拟DOM首次产生是React框架最先提出和使用的,其卓越的性能很快得到广大开发者的认可,继React之后vue2.0也在其核心引入了虚拟DOM的概念。在没有虚拟DOM的时候,我们在创建页面的时候一般都是使用HTML标签一个一个的去搭建我们的页面,既然有了DOM节点以后,为什么不直接使用原生DOM,那么原生DOM到底有什么弊端呢?原因是这个样子的,原生DOM中一个Node节点有N多的属性,一旦对DOM进行操作的时候会影响页面性能的核心问题主要在于DOM操作导致了页面的重绘或重排,为了减少由于重绘和重排对网页性能的影响,所以无论在什么项目中尽可能少的去操作DOM节点是性能优化的一大重点。

    为什么需要DOM?

    既然我们已经有了DOM,为什么还需要额外加一层抽象?

    • 1. 首先,前端性能优化的一个秘诀就是尽可能少地操作DOM,DOM相对较慢,而且频繁变动DOM会造成浏览器的回流或者重绘,这些都是性能的杀手,因此我们需要这一层抽象,在patch过程中尽可能地一次性将差异更新到DOM中,这样保证了DOM不会出现性能很差的情况。
    • 2. 其次,现代前端框架的一个基本要求就是无须手动操作DOM,不仅因为手动操作DOM无法保证程序性能,多人协作的项目中如果review不严格,可能会有开发者写出性能较低的代码,而且省略手动DOM操作可以大大提高开发效率。
    • 3. 最后,Virtual DOM最初的目的就是更好的跨平台,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么可以借助Virtual DOM,因为Virtual DOM本身是JavaScript对象。

    Virtual DOM的关键要素

    HTML:

    <div class="" id="app">
      <p class="text">节点一</p>
    </div>
    

    Javascript

    const createElement = () => {
      return {
        "tag":"div",
        "prop":{
          "id":"app"
        },
        "children":[
          {
            "tag":"p",
            "prop":{
              "class":"text"
            },
            "children":["节点一"]
          }
        ]
      }
    }
    

    上面的代码中,只是简单的使用了JavaScript语言简单描述了一下HTML部分相对应的代码,此时我们只需要再写入一个创建DOM的方法,按照文档描述将创建好的DOM按照层级添加到里面页面中就好了。

    上述JavaScript中所描述的数据类型也就可以简单的理解为是虚拟DOM,虽然这个虚拟DOM是那么的简陋,但是足可以说明情况啦,像Vue和React当需要对页面进行渲染更新的时候,则对比的就是虚拟DOM更新前后的差异,只对有差异的部分进行更新,大大减少了对DOM的操作。也就是我们经常所说的DIFF算法

    通过上述描述可以总结得出,由于原生DOM节点中的属性和方法过于复杂,操作时过于影响性能,所以使用Object来描述页面中的HTML结构,以达到对性能的提升。

    在明确了我们抽象的Virtual DOM构造之后,我们就需要一个函数来创建Virtual DOM.

    /**
     * 生成 vnode
     * @param  {String} type     类型,如 'div'
     * @param  {String} key      key vnode的唯一id
     * @param  {Object} data     data,包括属性,事件等等
     * @param  {Array} children  子 vnode
     * @param  {String} text     文本
     * @param  {Element} elm     对应的 dom
     * @return {Object}          vnode
     */
    function vnode(type, key, data, children, text, elm) {
      const element = {
        __type: VNODE_TYPE,
        type, key, data, children, text, elm
      }
    
      return element
    }
    

    参考:
    https://segmentfault.com/a/1190000019992100
    https://juejin.im/post/5d3f3bf36fb9a06af824b3e2

  • 相关阅读:
    【vim使用】光标的 段落切换、括号切换
    【vim使用】行数跳转 和 屏幕移动
    【vim使用】vim的三种工作模式
    【vim使用】vim的异常处理,删除交换文件
    【vim使用】打开文件,并且定位行
    【vim使用】vim新建文件、打开文件
    【vim使用】vim简介
    【终端使用】SSH免密码登录——02
    【终端使用】SSH免密码登录——01
    【终端使用】"apt"命令 安装/卸载软件
  • 原文地址:https://www.cnblogs.com/sunidol/p/11301754.html
Copyright © 2011-2022 走看看