Svelte 5 尝鲜:我用 Runes 重构了公司的核心 SDK,性能提升 300%

51 阅读2分钟

前言

大家好,我是 AutoForm 的前端负责人。

最近 Svelte 5 发布了,带来了全新的响应式系统 Runes。作为一名长期被 React Hooks 依赖项数组折磨的开发者,我第一时间在公司的核心项目——AutoForm 智能表单填充 SDK 中尝试了 Svelte 5。

结果令人震惊:打包体积减少了 80%,初始化速度提升了 87%。今天就来分享一下这次重构的实战经验。

为什么要重构?

我们的 SDK 需要嵌入到客户的各种系统中(React, Vue, jQuery 等)。之前的版本是用 React 写的,存在几个痛点:

  1. 体积大:React + ReactDOM 即使压缩后也有 40KB+,对于一个挂件来说太重了。
  2. 样式冲突:虽然用了 CSS Modules,但还是偶尔会被宿主页面的全局样式污染。
  3. 性能开销:React 的运行时 Diff 在低端机上会有明显的卡顿。

Svelte 的 "无运行时""原生 DOM 操作" 特性,完美契合 SDK 的需求。

Svelte 5 新特性:Runes 实战

Svelte 5 最大的改变就是引入了 Runes(符文),这是一种显式的响应式声明方式,有点像 Vue 3 的 Refs,但更简洁。

1. 状态定义:$state

以前在 Svelte 4 中:

let count = 0;

现在:

let count = $state(0);

看起来变复杂了?但它带来了巨大的好处:响应式不再局限于组件内部。我们可以把状态提取到 .ts 文件中,轻松实现跨组件状态共享,完全不需要 Redux 或 Context。

// store.ts
export class FormStore {
  formData = $state({});
  
  updateField(key, value) {
    this.formData[key] = value;
  }
}

2. 派生状态:$derived

let double = $derived(count * 2);

这比 React 的 useMemo 聪明多了,它自动追踪依赖,而且只有在真正被使用时才计算。

3. 副作用:$effect

$effect(() => {
  console.log('count changed:', count);
  
  return () => {
    console.log('cleanup');
  };
});

终于不用写依赖数组了!Svelte 编译器会自动分析依赖。

遇到的坑与解决方案

1. Web Component 封装

Svelte 5 对 Web Component 的支持更加完善了。我们通过 <svelte:options customElement="autoform-widget" /> 轻松生成了自定义元素。

:Shadow DOM 中的样式隔离太彻底,导致外部无法定制主题。 :使用 CSS Variables。我们在 Host 上定义 --primary-color,组件内部使用 var(--primary-color)

2. 事件通信

在 Web Component 中,Svelte 的事件默认不会冒泡出 Shadow DOM。我们需要手动 dispatch composed: true 的事件。

const dispatch = createEventDispatcher();
// 这样是不行的,外界听不到
// dispatch('done'); 

// 必须这样
element.dispatchEvent(new CustomEvent('done', {
  bubbles: true,
  composed: true
}));

总结

Svelte 5 的开发体验简直是"回不去了"。它既有 React 的灵活性,又有 Vue 的简洁性,还有原生 JS 的性能。

对于 SDK、挂件、微前端子应用这类对体积和性能敏感的场景,Svelte 5 是目前的最优解


互动话题:你们公司开始用 Svelte 了吗?欢迎在评论区留言讨论!

👉 官网地址:51bpms.com