无虚拟 DOM 框架
最近 Vue 在美国举办了 Vue Conf 2022,因为尤雨溪在 Vue Conf 上说他们正在探索一种新的编译策略,就是无虚拟DOM模式!
不知大家发现没有,自从2021年以来,无虚拟DOM框架/库/编译器获得了极大的关注,最为典型的两个项目:Svelte 和 SolidJS。
Svelte 是一种全新的构建用户界面的方法。传统框架如 React 和 Vue 在浏览器中需要做大量的工作,而 Svelte 将这些工作放到构建项目的编译阶段来处理。
与使用虚拟(virtual)DOM 差异对比不同。Svelte 编写的代码在应用程序的状态更改时就能有针对性的更新 DOM。
Svelte 的核心思想在于『通过静态编译减少框架运行时的代码量』。举例来说,当前的框架无论是 React Angular 还是 Vue,不管你怎么编译,使用的时候必然需要『引入』框架本身,也就是所谓的运行时 (runtime)。但是用 Svelte 就不一样,一个 Svelte 组件编译了以后,所有需要的运行时代码都包含在里面了,除了引入这个组件本身,你不需要再额外引入一个所谓的框架运行时!
当然,这不是说 Svelte 没有运行时,但是出于两个原因这个代价可以变得很小:
Svelte 的编译风格是将模板编译为命令式 (imperative) 的原生 DOM 操作。比如这段模板:
<a>{{ msg }}</a>
会被编译成如下代码:
function renderMainFragment ( root, component, target ) {
var a = document.createElement( 'a' );
var text = document.createTextNode( root.msg );
a.appendChild( text );
target.appendChild( a )
return {
update: function ( changed, root ) {
text.data = root.msg;
},
teardown: function ( detach ) {
if ( detach ) a.parentNode.removeChild( a );
}
};
}
可以看到,跟基于 Virtual DOM 的框架相比,这样的输出不需要 Virtual DOM 的 diff/patch 操作,自然可以省去大量代码,同时,性能上也和 vanilla JS 相差无几(仅就这个简单示例而言),内存占用更是极佳。这个思路其实并不是它首创,之前有一个性能爆表的模板引擎 Monkberry.js 也是这样实现的,ng2 的模板编译其实也跟这个很类似(但是中间加了一层渲染抽象层)。