自jQuery和常规HTML页面问世以来,现代前端已经走了很长一段路。 现在,我们有了汇编程序,程序包管理器,组件方法,SPA,SSR等。
看来我们拥有幸福所需的一切。 但是行业正在向前发展。 我想告诉您有关已编译的Svelte框架及其相对于类似物的优点。

图片由安德鲁·沃尔波尔
Google趋势
为了了解前端的当前状况,我分析了过去5年在Google趋势中查询关键词,React,jQuery,Vue,Angular在俄罗斯的流行程度。

Google趋势
在过去的5年中,与jQuery相关的查询数量已大大减少,而让给了组件框架。 尽管jQuery失去了基础,但它仍然是流行的开发工具。
从该图可以得出结论,组件库赢得了前端,React是俄罗斯的领导者。
劳动力市场
我们不仅为自己编写代码,而且还为金钱编写代码。 主要是为了钱。 因此,孤立于劳动力市场而考虑框架的流行是愚蠢的。
根据hh上的空缺数量,React排名第一,其次是jQuery和其他组件库。 如果我们查看以关键技能指出有问题的库的申请人数,那么jQuery知道的申请人数是React的5倍。 比Angular大15倍。

劳动力市场
从该图可以得出以下结论:
- 组件框架在雇主中最受欢迎,其中最受欢迎的是React。
- 在申请人中,最常用的库是jQuery。
因此,组件框架获得了成功。 前端解决了开发人员在jQuery期间遇到的问题。 但是新方法带来了新的麻烦。 我看到什么问题?
- 性能。
今年1月,Google宣布可以在Google Play上发布PWA应用程序,为在本机应用程序商店中使用javascript铺平了道路。 这给开发人员带来了一定的责任,因为用户期望本机应用程序的性能,所以对于消费者而言应该没有任何区别。
Javascript还征服了低功耗设备。 这是一款智能电视,手表,物联网。 此类设备的内存和处理器预算有限,因此开发人员无法负担将资源浪费在用户身上。
在工作中,我们具有在Internet集线器上运行React应用程序的经验。 原来马马虎虎。 - 高入门门槛。
正如我们在上面看到的,大多数求职者都指向jQuery技能,而不是反应。 掌握React概念比连接到jQuery页面并开始创建要困难得多。 - 对框架的依赖。
如果您有用React编写的组件库,则不太可能在Vue或Angular项目中重用它。 您成为生态系统的人质。
苗条 香草味。
今年4月,发布了编译后的Svelte框架的第三个版本。
Svelte为开发人员提供了编写高级声明性代码的能力,这些声明性代码经过编译后会变成低级命令性代码。 这也使得进行有效的树状摇动成为可能,因此可以向客户端发送最小的捆绑包。
让我们看看Svelte为解决这些问题提供了哪些解决方案。
由于React是俄罗斯最受欢迎的库,因此将在React上提供更多示例。
1.表现
如果您开始熟悉新库,那么很可能会从“待办事项”列表开始游览。 这是一个相当简单的任务,通常在香草中更容易编写。 如果您想更深入地研究框架,那么对Real World Application进行回顾是一个不错的选择。 这是本质上是Medium的克隆的博客。 有注册,授权,创建帖子,评论,喜欢。 框架专家编写该功能的实现,并将其添加到“ 真实世界应用程序”集合中。
FreeCodeCamp上发表了一篇有关比较用不同框架编写的Real World Application的文章。
如果我们看看最终捆绑包的大小,那么斯维尔特的表现将超过其竞争对手。 仅9.7kb的代码发送到客户端。 结果,它花费更少的时间来传输数据,解析和处理您的代码。

实际应用程序捆绑包大小比较
最好的代码不是书面代码。
如果我们看一下编写应用程序功能所需的代码行数,那么Svelte将需要大约1000行,而React需要大约2000行。应用程序中的代码越少,错误越少,支持也就越容易。

实际应用代码大小比较
让我们看一下性能。 js-framework-benchmark提供了前端框架之间渲染性能的比较。 测试是绘制一张包含大量行的表。 对该表进行进一步的操作:部分或全部更新,创建,清理,删除行。
通过更新时间,Svelte显示了最佳或可比的时间。 Svelte非常平衡,执行不同类型的操作时不会变形。

比较更新执行时间,毫秒
如果我们查看消耗的内存量,那么Svelte在所讨论的库中是最不活跃的。

比较消耗的内存量,mb
我不习惯说话,而是决定自己检查所有内容。 我找到了前端DBMonster基准的实现,并重写了React 16.8和Svelte 3上的实现。测试包括渲染表,然后更新行。

DBMonster测试是什么样的?
在测试期间,Svelte消耗的内存减少了10 MB,并且更新速度比React快10毫秒。


苗条/反应
上面的测试是综合的,但是从中可以得出结论,在Svelte上进行开发时,您会发现:
2.高准入门槛
如果我们看一下React上最简单的组件,那么您需要导入React本身,编写一个将返回标记并导出您的组件的函数。 总共3行代码。
import React from 'react'; const Component = () => (<div>Hello</div>); export default Component;
如果我们看一下svelte上组件的最简单示例,那么您只需编写标记。 总共1行代码。
<div>Hello</div>
严格来说,最简单的Svelte组件是一个空文件。 这样就可以从空文件为您的应用程序创建模板,然后开始开发。 在这种情况下,什么都不会中断。
您还可以采用从排字机接收到的布局,并将其立即用作Svelte组件,而无需进行其他转换。 有效的html是Svelte组件。
我想分享一个关于中间反应开发人员职位的访谈中的例子。
setFilter() { this.switchFlag = !this.switchFlag } ... <button onClick={setFilter}>Filter</button>
候选人试图将过滤器按钮的状态直接保存到class属性中。 尽管有它的名字,React仍然没有足够的反应能力来应对这种变化。 这表明即使是中级开发人员也很难获得React使用的状态更新模式。
让我们看一下通过单击增加计数器数量的按钮示例。

在React上,您需要一个变量来保存状态和一个可以更新状态的函数。 接下来,您需要为按钮本身分配用于更新的处理程序。 总共,我得到了8行代码。
import React from 'react'; const Component = () => { const [count, setCount] = React.useState(0) return <button onClick={() => setCount(count + 1)}> Clicked {count} </button> } export default Component;
要解决Svelte上的类似问题,您需要一个变量来存储状态。 在处理程序中,您只需更改该变量的值即可。 总共6行代码。
<script> let count = 0; </script> <button on:click={()=>count+=1}> Clicked {count} </button>
让我们使示例复杂一些。 假设我们需要一个输入字段,在其旁边显示其状态。

在React上,我们仍然需要一个变量和函数来更新状态。 然后,在输入字段中,您需要传输当前值并为更改分配一个处理程序。 我最终得到了11行代码。
import React from 'react'; const App = () => { const [value, setValue] = React.useState(''); return ( <React.Fragment> <input value={value} onChange={e => setValue(e.target.value)} /> {value} </React.Fragment> ); } export default App;
要在Svelte上解决此问题,您需要一个存储状态的变量,然后在输入字段中进行双向绑定。 总共5行代码。
<script> let value = ''; </script> <input bind:value={value}/> {value}
如果您曾经动手在React上从DOM中移除元素,那么我很同情您。 React将需要一个包装器,该包装器将延迟从DOM中删除元素并制作动画,或者该元素将保留在DOM中,但是动画将需要控制display属性或其他操作,以便该元素不占用空间。

我试图在React上找到最简单的实现,最后我得到了35行代码。 如果您有更简单的解决方案,请分享评论。
淡入淡出反应 import React from "react"; import "./style.css"; const App = () => { const [visible, setVisible] = React.useState(true); return ( <React.Fragment> <button onClick={() => setVisible(!visible)}>toggle</button> <div className={visible ? "visible" : "invisible"}>Hello</div> </React.Fragment> ); }; export default App;
.visible { animation: fadeIn 0.5s linear forwards; } .invisible { animation: fadeOut 0.5s linear forwards; } @keyframes fadeOut { 0% { opacity: 1; } 100% { opacity: 0; display: none; } } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } }
在Svelte上,类似的组件仅需要8行代码。 Svelte具有用于管理动画的内置模块。 导入所需类型的动画,然后说出添加和删除时如何对组件进行动画处理。
<script> import { fade } from 'svelte/transition'; let visible = true; </script> <button on:click={()=>visible=!visible}>toggle</button> {#if visible} <div transition:fade>Hello</div> {/if}
兼容性使Svelte可以为开发人员提供出色的抽象。 而且,如果您不使用它们,它们将不会落入最终的捆绑包。
例如,过渡模块具有很酷的交叉淡入淡出功能,当从一个DOM节点移动到另一个DOM节点时,该模块使您可以对组件进行动画处理。 使用它,您可以在“待办事项”列表中进行此类任务转换。

酷抽象的另一个示例是use:指令。 它允许您将自定义处理程序分配给DOM元素。 在下面的示例中,仅使用一个功能处理按下和移动事件以及触摸事件。

在认识Svelte之后,我的朋友们通常说,自jQuery以来,他们还没有经历过这种有趣的前端开发。
3.对框架的依赖
当React到达时,网络上有很多jQuery小部件。 在React上找到合适的组件很困难。 然后,用于jQuery小部件的包装器开始出现,它们能够同步React和jQuery。 之后,用React本身编写的组件已经开始出现。
现在,React本身也有类似情况。 有很多现成的解决方案和库,它们使您无法轻松地转移到另一个框架。
斯维尔特提供什么? 编译后,您的代码将变成常规的JS,不需要运行时。 这样就可以在其他框架中使用Svelte组件。 您只需要一个通用包装。 例如,用于React和Vue svelte-adapter的适配器 。 通过将组件包装在适配器中,可以将元素用作常规组件。
import React from "react"; import SvelteSpinner from "svelte-spinner"; import toReact from "svelte-adapter/react"; const Spinner = toReact(SvelteSpinner, {}, "div"); const App = () => <Spinner size={50} />

Svelte支持在自定义元素中进行编译,这进一步扩大了组件的应用范围。 您可以在custom-elements-everywhere上看到各种框架对自定义元素的支持。
个人经历
我还不能在Svelte上班,因为我们正坐在React生态系统上,但是我有个人项目。
我以前曾写过如何在Google Play上发布我的Metalz应用程序。

根据我的感觉,Svelte使您可以编写更简洁和易于理解的代码,同时提供了广泛的工具来简化实现。
缺点
像任何年轻的框架一样,Svelte拥有一个小型的现成解决方案生态系统,并且很少有文章可以找到最佳实践。 因此,我不建议立即将Svelte用于大型项目,因为您可能会陷入体系结构的死胡同。
在小项目上尝试Svelte,我相信您会喜欢的。