一. svelte
介绍
svelte
是前端框架,开发体验与Vue
类似,使用template
语法。本文主要解析svelte
与react
的渲染流程差异和svelte
的signals
机制。
svelte
使用示例
javascript
// App.svelte
<script>
let count = $state(0)
const increment = () => {
count += 1
}
</script>
<div>
<button onclick={increment}>
count is {count}
</button>
</div>
// main.js
import { mount } from 'svelte'
import App from './App.svelte'
const app = mount(App, {
target: document.getElementById('app'),
})
export default app
二. svelte
原理
svelte
编译原理部分本文不做介绍,这里需要知道的是svelte
首先会编译组件template
,将其转换成对应的组件方法,在编译转换的过程中有一些优化机制,核心是优化运行时的性能。
例如下面这段代码,编译转换后的结果如下
javascript
// Counter.svelte
<script>
let count = $state(0)
const increment = () => {
count += 1
}
</script>
<button onclick={increment}>
count is {count}
</button>
// 转换后
const increment = (_, count) => {
$.set(count, $.get(count) + 1);
};
var root = $.template(`<button> </button>`);
function Counter($$anchor, $$props) {
$.push($$props, true, Counter);
let count = $.state(0);
var button = root();
button.__click = [increment, count];
var text = $.child(button);
$.reset(button);
$.template_effect(() => $.set_text(text, `count is ${$.get(count) ?? ''}`));
$.append($$anchor, button);
return $.pop({ ...$.legacy_api() });
}
export default Counter;
2.1 渲染流程
svelte
渲染流程中使用了虚拟DOM
树,相比React
,svelte
的虚拟DOM
树更加精炼,对于一些静态的节点并不会创建其对应的虚拟DOM
节点,只会创建动态节点对应的虚拟DOM
节点。
例如下面这段代码,在React
渲染流程中,div
和两个h1
标签都会创建对应的Fiber
节点,但是在svelte
中,只会创建第二个h1
标签的文本节点对应的虚拟DOM
节点,所以svelte
构建的虚拟DOM
树占用的内存开销和运行性能都比React
要好得多。
javascript
<div>
<h1>hello world</h1>
<h1>{count}<h1>
</div>
在首次渲染中,会采用深度优先遍历算法递归创建虚拟DOM
节点,且同时创建其对应的真实DOM
节点,然后会将真实DOM
节点插入到父DOM
节点中,当整个虚拟DOM
树构建完成后,会将创建好的真实DOM
树插入到页面指定节点上完成首次渲染流程。
当状态更新时,会触发更新渲染,与React
不同的是,svelte
不会重新创建新的虚拟DOM
树,而是递归遍历当前虚拟DOM
树,找到需要更新的虚拟DOM
节点,然后执行更新逻辑。需要注意的是更新时机和React
一样都是异步的。
2.2 signal
svelte
的signal
对象数据结构如下,核心关注以下属性:
v
属性记录当前状态,例如state
的初始值reactions
属性记录依赖该signal
的虚拟DOM
节点,当signal
状态变更时会触发reactions
属性记录的虚拟DOM
节点更新渲染equals
属性用于判读signal
状态是否变更
javascript
var signal = {
f: 0,
v,
reactions: null,
equals,
rv: 0,
wv: 0
};
三. 总结
svelte
在编译阶段有一些优化机制,优化运行时的性能。在渲染流程中构建的虚拟DOM
树相比React
也更加精炼,当触发更新渲染时,只需要找到需要更新的虚拟DOM
节点,执行其对应的更新逻辑即可。svelte
是一个很优秀的框架,在内存开销和运行性能上都做到了极致。