svelte原理解析

一. svelte介绍

svelte是前端框架,开发体验与Vue类似,使用template语法。本文主要解析sveltereact的渲染流程差异和sveltesignals机制。

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树,相比Reactsvelte的虚拟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

sveltesignal对象数据结构如下,核心关注以下属性:

  • 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是一个很优秀的框架,在内存开销和运行性能上都做到了极致。

相关推荐
前端不太难2 分钟前
Navigation State 与页面内存泄漏的隐性关系
前端·ui·react
C+++Python7 分钟前
如何选择合适的锁机制来提高 Java 程序的性能?
java·前端·python
IT_陈寒14 分钟前
JavaScript 性能优化:7 个 V8 引擎偏爱的编码模式让你提速 40%
前端·人工智能·后端
小oo呆25 分钟前
【自然语言处理与大模型】LangChainV1.0入门指南:核心组件Messages
前端·javascript·easyui
郑州光合科技余经理27 分钟前
技术解析:如何打造适应多国市场的海外跑腿平台
java·开发语言·javascript·mysql·spring cloud·uni-app·php
果壳~1 小时前
【前端】【canvas】图片颜色填充工具实现详解
前端
Bigger1 小时前
Tauri (23)——为什么每台电脑位置显示效果不一致?
前端·rust·app
¥懒大王¥1 小时前
XSS-Game靶场教程
前端·安全·web安全·xss
ssshooter1 小时前
为什么移动端 safari 用 translate 移动元素卡卡的
前端·css·性能优化
不会飞的鲨鱼1 小时前
抖音验证码滑动轨迹原理(很难审核通过)
javascript·python