虚拟dom与Vue,vapor-Mode

前言

Svelte和SolidJS的兴起重新非虚拟DOM框架的模式引入公众视野。到2024,虚拟dom好像被市场尝试慢慢抛弃,Vue正在构建无虚拟dom的版本.....

虚拟dom

优点

  1. HTML 模板的高度抽象。受限于 html 语法限制,我们难以复用 HTML 节点;而使用 Virtual DOM,我们能够用 JS 描述 DOM 节点,从而带来了复用 HTML 模板的能力,提高效率。

  2. 跨平台。抽象出了 Virtual DOM 数据结构后,就可以适配 DOM 之外的渲染目标,如移动端(Weex)。

    现代前端科技解析 ------ Virtual DOM - 404Forest

  1. 利用虚拟dom,可以将一些html的属性抽象成js属性,减少对对真实dom的读取或操作,从而提升性能。对JS的操作比dom的操作会更加灵活和拓展性更强
  2. uniapp等跨平台框架实现的核心。

缺点

  1. 首次渲染性能低,第一次需要全量构建虚拟dom。
  2. 运行时内存占用大,需要维护一份虚拟dom tree的内存副本。
  3. 生成虚拟dom所需的成本。

VUE与虚拟dom

生成时机

vue利用parser将template转成AST,然后经过优化,而后通过代码生成器生成render函数,执行生成虚拟dom。而后通过数据更换和监测,传入数据可生成实时的虚拟dom,进行patch->diff后生成dom。

数据结构

本点以下内容复制来自现代前端科技解析 ------ Virtual DOM - 404Forest

本文实现的 Virtual DOM 参考 Vue,结构简化,如下:

typescript 复制代码
interface VNode {
  type?: 'Element' | 'Text' | 'Comment',
  tag?: string,
  data?: VNodeData,
  children?: Array<VNode>,
  text?: string,
  elm?: Node  // 对应的真实 DOM 节点
}
interface VNodeData {
  key?: string,
  ref?: string,
  events?: {
    [key: string]: any
  },
  attrs?: {
    [key: string]: any
  },
  rawAttrs?: {
    [key: string]: any
  },
  directives?: {
    [key: string]: any
  }
}

template到render

转换前:

xml 复制代码
<div class="container">
  <!-- test -->
  <button v-on:click="clickHandler">click me</button>
   <ul :class="testClass" v-if="show">
     <li v-for="city in arr" >{{city}}</li>
   </ul>
 </div>

转换后:

less 复制代码
function render() {
  with(this) {
    return _c('Element', 'div', {attrs: {class: 'container',},events: {},}, [
      _s(`
      `),
      _m(` test `),
      _s(`
      `),
      _c('Element', 'button', {attrs: {},events: {click: clickHandler},}, [
        _s(`click me`)
      ]),
      _s(`
      `),
      // v-if
      (show) ? _c('Element', 'ul', {attrs: {class: testClass,},events: {},}, [
        _s(`
        `),
        // v-for
        ...(() => {
          return arr.map(city => {
            return _c('Element', 'li', {attrs: {},events: {},}, [_s(city)])
          })
        })(),
        _s(`
      `)]) : _e(),_s(`
      `)
    ])
  }
}

创建真实dom

ini 复制代码
// 根据 VNode 创建真实 dom,并附着在 VNode.elm 属性上
function createDOM(node: VNode) {
  let $node: Node
  if(node.type === 'Element') {
    $node = document.createElement(node.tag)
    node.children.forEach(e => {
      $node.appendChild(createDOM(e))
    })
    updateProps($node, node.data.attrs, {})
    updateEvents($node, node.data.events, {})
  }
  if(node.type === 'Text') {
    $node = document.createTextNode(node.text)
  }
  if(node.type === 'Comment') {
    $node = document.createComment(node.text)
  }
  node.elm = $node
  return $node
}

发展历程

Vue1.0的时候还是真实dom,Vue2.0去除了运行时的 HTML Parser,全面拥抱虚拟dom,Vue3.0又在尝试剥离虚拟dom,推出了Vue的蒸汽模式(Vapor Mode)。

Vue next--Vapor Mode

vuejs/core-vapor: Vue Vapor (no virtual DOM) Experimental repo. (github.com)

  1. 一个全新的编译策略
  2. 相同的模板语法,但编译后的代码性能更高。
  3. 利用 Template标签克隆元素 + 更精准的绑定,并且没有虚拟 DOM

只支持 Composition API 和带有

在应用级别,使用 Vapor Mode 编译的应用能够完全移除虚拟DOM运行时,只包含极简轻量的 @vue/reactivity 和 vapor 模式运行时辅助代码。这样一个应用的基础大小只有约6kb,相比目前含虚拟DOM的 Vue 3 应用的约50kb,缩减了88%。

即将到来的 Vue 3 "Vapor Mode" - 知乎 (zhihu.com)

参考

现代前端科技解析 ------ Virtual DOM - 404Forest

即将到来的 Vue 3 "Vapor Mode" - 知乎 (zhihu.com)

相关推荐
星之卡比*1 分钟前
前端面试题---vite和webpack的区别
前端·面试
^^为欢几何^^6 分钟前
npm、pnpm和yarn有什么区别
前端·npm·node.js
前端菜鸟日常13 分钟前
vue2和vue3的按需引入的详细对比通俗易懂
javascript·vue.js·ecmascript
AC-PEACE28 分钟前
Vue 中 MVVM、MVC 和 MVP 模式的区别
前端·vue.js·mvc
播播资源30 分钟前
ChatGPT付费创作系统V3.1.3独立版 WEB端+H5端+小程序端 (DeepSeek高级通道+推理输出格式)安装教程
前端·ai·chatgpt·ai作画·小程序·deepseek·deepseek-v3
冷琴199638 分钟前
基于Python+Vue开发的反诈视频宣传管理系统源代码
开发语言·vue.js·python
zhrb1 小时前
打开Firefox自动打开hao360.hjttif.com标签解决方案
前端·firefox
安大桃子1 小时前
Cesium实现深色地图效果
前端·gis·cesium
程楠楠&M1 小时前
uni-app(位置1)
前端·javascript·uni-app·node.js
破z晓1 小时前
uniapp 整合openlayers 编辑图形文件并上传到服务器
前端·javascript·uni-app