虚拟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)

相关推荐
Autumn_ing3 小时前
Design.md生成UI怎么验收?举例运营后台的颜色、状态和数据核对
前端·ui·ai·设计系统·paico·ai生成ui·design.md
keyipatience4 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
朱涛的自习室4 小时前
我给 Gemini 4 和 DeepSeek 搞了套「末位淘汰」,AI 干活会更猛吗?(Day 3)
android·前端·后端
java1234_小锋6 小时前
【技术专题】HTML5 网页技术 - HTML5简介 & HTML5 文档结构
前端·html·html5
鶴哥只手遮天7 小时前
Vue 3 核心源码深度剖析系列(v3.5.44)-第 1 章 项目全景:monorepo 架构与工程化体系
前端·vue.js·开源
流星。。方7 小时前
小团队官网SEO落地:前端语义化与静态生成的工程实践
前端·状态模式
用户530429765797 小时前
盘点危化品搬运诊断的6类工具与自处理边界判断
前端
curtain7 小时前
从古法编程到 Agent:我入行这两年,AI 改变了什么
前端·openai
zyfts7 小时前
10分钟自制Codex钉钉通知Skill:AI干完活自动钉钉提醒你
前端
大孜然7 小时前
孜然QQ频道自动化程序机器人配置教程
前端