Snabbdom

Snabbdom 简介与快速上手

了解虚拟 DOM 是什么、Snabbdom 和 Vue2 的关系,并完成第一个虚拟 DOM 渲染示例。

🎯 引言

学完这篇文章,你将明白虚拟 DOM到底是什么、Snabbdom 是做什么的,以及它和 Vue2 之间的关系。我们还会一起搭建练习环境,用不到 20 行代码完成第一次虚拟 DOM 渲染。


🧱 什么是虚拟 DOM

我们知道,页面是由一个个 DOM 元素组成的。直接操作 DOM 有两个麻烦:一是写起来繁琐,二是频繁改动会触发浏览器反复重排重绘,性能开销大。

虚拟 DOM(Virtual DOM)就是用 JavaScript 对象来描述 DOM 结构。比如一个真实的 div

<div id="app">Hello</div>

用虚拟 DOM 描述,就是一个普通的 JS 对象:

const vnode = {
    sel: 'div#app',
    text: 'Hello'
};

你可以把它理解成施工图纸:真实 DOM 是盖好的房子,虚拟 DOM 是图纸。改动时先画一张新图纸,把新旧图纸对比一遍,只在房子上改动有差异的地方,而不是整栋推倒重建。


🧱 Snabbdom 是什么

Snabbdom 是一个专注于虚拟 DOM 的 JavaScript 库,名字来自瑞典语,意为"敏捷、迅速"。它有两个鲜明的特点:

  • 小巧:核心代码只有约 200 行,没有历史包袱,非常适合学习。
  • 模块化:核心只负责创建和对比虚拟节点,样式、属性、事件等功能全部通过"模块"按需加载。

最值得一提的是:Vue2 的虚拟 DOM 实现,正是基于 Snabbdom 改造而来的。也就是说,学好 Snabbdom,就等于摸到了 Vue2 底层的脉搏。

Vue3 的虚拟 DOM 是自研的,但核心思想(虚拟节点、Diff、key)与 Snabbdom 一脉相承,学完本课程对理解 Vue3 同样有帮助。

🚀 搭建练习环境

本课程环境使用 Node.js v22.0.0,对应的 Snabbdom 版本为 3.6.4

虚拟 DOM 最终要渲染到浏览器页面上,我们用 Vite 创建一个最简项目(Vite 在 Stage4 已经学过):

npm create vite@latest snabbdom-demo -- --template vanilla
cd snabbdom-demo
npm install
npm install snabbdom@3.6.4

启动开发服务器:

npm run dev

浏览器打开终端里提示的地址(通常是 http://localhost:5173),看到 Vite 的欢迎页就说明环境没问题了。


📦 第一个示例:渲染并更新页面

打开 main.js,把模板自带的代码清空,写入:

main.js
import { init, h } from 'snabbdom';

// init 用来创建 patch 函数,先传一个空数组,第三篇再细讲
const patch = init([]);

// 用 h 函数创建一个虚拟节点:一个 id 为 container 的 div
const vnode = h('div#container', 'Hello Snabbdom');

// 把虚拟节点渲染到页面上
const container = document.getElementById('app');
patch(container, vnode);

index.html 里需要一个挂载点(vanilla 模板自带):

index.html
<div id="app"></div>

保存后浏览器里就能看到 Hello Snabbdom。此时页面结构变成了:

<div id="container">Hello Snabbdom</div>

接着试试更新。在代码末尾追加:

main.js
// 画一张"新图纸",对比后更新页面
const newVnode = h('div#container', '你好,虚拟 DOM');
patch(vnode, newVnode);

页面文字会瞬间变成"你好,虚拟 DOM"。注意第二次调用 patch 传的是上一次的 vnode 和新 vnode——这就是"新旧图纸对比"的过程。

这段代码涉及三个核心角色,先记住名字,后面每篇都会深入:

角色作用
h创建虚拟节点(画图纸)
init创建 patch 函数(可注册模块)
patch对比并更新真实 DOM(按图施工)

🧾 小节总结

  • 虚拟 DOM 是用 JavaScript 对象描述 DOM 结构,更新时对比新旧两棵树,只改差异部分。
  • Snabbdom 是一个小巧、模块化的虚拟 DOM 库,核心仅约 200 行代码。
  • Vue2 的虚拟 DOM 基于 Snabbdom 改造,学它就是学 Vue2 的底层。
  • 本课程使用 Node.js v22.0.0 和 Snabbdom 3.6.4,用 Vite vanilla 模板搭建练习环境。
  • 三个核心角色:h 创建虚拟节点,init 创建 patchpatch 负责渲染和更新。

❓ 知识问答

Q1:虚拟 DOM 一定比直接操作 DOM 快吗?

A:不一定。虚拟 DOM 的价值在于"用 JS 计算换取最少的 DOM 操作",并提供更好的开发体验。首次渲染时它反而多了一层计算开销。它不是银弹,但在数据频繁变化的界面里收益巨大。

Q2:Snabbdom 能直接用来做真实项目吗?

A:可以,但它定位偏底层,一般被框架集成使用(如 Vue2)。日常开发我们更常用 Vue、React 这类框架,学 Snabbdom 主要是为了理解底层原理。

Q3:为什么不直接用 script 标签引入 Snabbdom?

A:Snabbdom 3.x 以 ES 模块发布,配合 Vite 这类开发工具最省事,保存代码还能自动刷新页面,学习体验更好。

Q4:h 函数的名字是什么意思?

A:h 是 hyperscript 的缩写,意为"用脚本(JavaScript)书写 HTML",是虚拟 DOM 领域约定俗成的命名。


🧪 小练习

  1. 按本篇步骤创建 snabbdom-demo 项目并安装 snabbdom@3.6.4
  2. 修改 main.js,渲染出一个 idbox、内容为"我的第一个虚拟节点"的 section 元素,然后再把它更新为"内容更新啦"。
main.js
import { init, h } from 'snabbdom';

const patch = init([]);

// 请在这里编写代码

🎉 恭喜你已经完成了 Snabbdom 的入门!下一篇我们深入学习 h 函数,看看它能描述出多么复杂的页面结构。