svelte 是什么?
svelte
是一个组件化、响应式 的前端库。与传统的 react 、vue-core 而言,svelte 更偏向编译时,在编译侧的工作量较高。
目前市面上最常见的前端框架有三种 vue、react 、angular 。其中 vue、react 都采用的 虚拟DOM 的方式,而 ng 则采用了 脏数据检测 。 无论是虚拟DOM还是脏检测 ,最终的响应式操作都指向了 运行时 。这里 运行时
指的是,每次在数据更新时,通过框架核心的处理,对比出需要更新的位置,进而进行更新。
而 svelte
则是不同的,svelte 将重点放在了编译侧(这里并不是说 svelte 没有运行时,而是运行时的体积更小),svelte 在编译时,将变量的指针更新操作封装在了 $$invalidate 函数中,实现在数据更新时,自动更新 DOM 的功能。
暂留问题:运行时的定义到底是什么? ...
与 vue、react、ng 的区别
与 vue、react之间的区别不同,vue 、react 的区别更偏向于应用侧,如 diff 算法的区别、开发者的区别、相同体积下的性能区别、双向绑定的支持与否 等。
而 svelte 与他们的区别在更底层,它从核心开始就与传统框架走了两条不同的路。
响应式原理
react
、vue
的响应式原理都是 虚拟DOM ,在状态更新时,触发 虚拟DOM 的更新,进而更新真实 DOM。 流程大概是这样的,状态变更 -> 生成新的虚拟 DOM -> 对比新旧两个虚拟 DOM -> 将需要更新的 DOM 压入队列中 -> 批量更新 DOM。
而 svelte
的响应式的原理是在静态分析阶段分析出哪些变量是需要响应的,再通过对应的更新操作维持响应式。
关于 vue1.0:
如果你接触前端足够早,学过 vue1,你会发现 svelte 中的代码,和 vue1 的代码极其相似,且 vue1 也没有使用虚拟 DOM。那你可能会疑惑他们的区别是什么?
区别:
- 编译 & 运行:vue1 本质上还是运行时解析模板代码,而 svelte 则是在编译时,将代码转换成 JS 代码。
- 响应式:vue1 通过
Object.defineProperty
的getter
、setter
实现响应式追踪依赖,而svelte
则是在编译时分析依赖以及依赖属性的变化,封装数据变化的表达式,进而实现更新时的 DOM 更新。 - 生态:关于 svelte 生不逢时进而导致的生态不够完善问题
虚拟DOM
虚拟DOM 的出现原因是,前端框架早期对于局部的全量更新导致 DOM 操作过多,以及不能进行批处理操作,进而导致性能变差(典型问题:react fiber 的开发原因)。
虚拟 DOM 的优缺点都很明显,优点就是灵活。由于有了中间层,可以进行各式各样的魔法操作。而缺点则是性能,无论是虚拟DOM 所占用的内存,还是每次更新的 diff 算法,都会消耗一定的性能。
关于 虚拟DOM 和 真实DOM 的性能问题
很多人总说虚拟DOM的性能比真实性能高,其实这段话是有一定误解的,\ 在简单的代码中,虚拟DOM要比真实DOM更消耗性能的。
之所以性能高的原因是,虚拟DOM免去了无用的 DOM 操作,以及 DOM进行了批处理操作,避免了回流回流重绘的性能消耗
静态分析
静态分析顾名思义,针对静态代码进行拆分解析。像我们大学时期的编译原理课程,基本都在做静态分析(词法分析、语法分析...)。
像我们现在使用的 react 、vue 实际上也进行了静态分析,将 jsx 、vue 文件转换为 JS 文件。将文件中的代码通过静态分析转换为 JS 代码。
react 、vue 和 svelte 的静态分析有什么不同
传统框架进行的静态分析是纯粹的,主要任务就是将你写的代码转换成浏览器能看懂的 JS
代码,甚至于你可以直接写他们分析过的代码(如果你写过 vue
的 render
应该不难发现)。
而 svelte
则进行了纯粹的静态分析之外的事,比如它的响应式是通过静态分析,发现了变量的 赋值、更新、突变 操作,同时也发现了变量在模板语法中的使用,进而将变量的更新绑定页面 DOM 变化的驱动。
svelte
静态分析时,可以分析到哪些变化,哪些监听不到?监听不到的变化怎么办?
通过静态分析,分析变量的改变,分析的方案有以下几种
- 赋值
name = 'sincenir'
- 更新
num += 1
- 突变
user.name = 'sincenir'
分析不到的情况:
array.push('水果')
- array.....
分析不到的解决方案:
- 通过新的赋值更新操作,驱动依赖分析。如: array = array
为什么静态分析为什么只支持 赋值、更新、突变 操作?
svelte
的依赖分析是基于静态分析的,对于赋值、更新、突变,编译器可以通过针对 =
的分析,在编译时确定它们会改变哪些数据,因此可以生成对应的依赖。
但对于更复杂的操作而言,编译器可能无法在编译时确定它们会改变哪些数据,因此无法生成相应的代码来更新 DOM。
最后
都说 天下大势、分久必合、合久必分 。
其实在看的框架越来越多之后,会慢慢发现框架之间的趋同化。
虽然每年都有新兴框架都在试图找一个不同的方向改变人们的心智,但随着框架的发展就会发现,新兴的框架和老框架越来越像。
svelte
曾试图这么干,但最终也由于一些语法糖,不得不提供一些运行时的功能,进而逐步减弱其初期特色以满足大众需求。
如果前端整体表现形式不变的情况下,基本不再会出现颠覆式的框架了。他们只能以不同的底层架构做出来一些使用上相同的框架。
但它们终归还是有一些区别,适用于不同的人群,具体可以期待后续的对比文章。
文章规划
我这里对 svelte
的介绍大概会分为以下几篇文章:
- svelte 的基础介绍
- svelte 的上手难度
- svelte 的架构设计
- svelte 的框架对比(性能、生态、问题等)
- svelte 的入门指南
- svelte 的高阶操作(魔法)
这些文章逐个介绍 svelte
这个框架。
在这些文章都完成后,我会合成一篇至少 2W+ 字的 《svelte指南》 合成篇。