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

相关推荐
pany4 分钟前
做 AI 友好的开源 Vue3 模板 🌈
前端·vue.js·ai编程
小二·27 分钟前
React 19 + Next.js 15 现代前端开发实战:App Router / Server Components / 流式渲染
前端·javascript·react.js
daols881 小时前
vue 甘特图 vxe-gantt 小时视图设置日期轴每间隔 3 个小时
vue.js·甘特图·vxe-gantt
谙忆10242 小时前
前端图片直传对象存储:OSS/S3 预签名 URL、STS 临时凭证与回调校验
前端
CHNE_TAO_EMSM3 小时前
Android studio 打开文件时自动下载源码
前端·javascript·android studio
一孤程4 小时前
Airtest自动化测试第五篇:小程序与Web测试——跨平台自动化全覆盖
前端·自动化测试·小程序·自动化·测试·airtest
IT_陈寒4 小时前
SpringBoot自动配置不是你以为的那样的智能
前端·人工智能·后端
yume_sibai5 小时前
大屏数据可视化 - 边框红绿呼吸灯实现详解
前端·信息可视化·typescript
Hyyy5 小时前
很多Desktop都在上的Computer Use是什么
前端·llm
慢功夫5 小时前
开篇:VS Code 为什么不是一个普通 React App
前端·visual studio code