我们为什么要使用框架? Angular,React和Vue帮助我们构建复杂的Web应用程序:结构代码,管理状态和开发复杂的界面。 在过去的十年中,框架已成为标准。 昂贵的标准。 由于框架已投入使用,因此JS非常膨胀。 还有更多的页面,重达几兆字节,而其中很大一部分是框架本身。 似乎有点少,但是对用户来说却很关键-在电话或弱互联网上,该页面甚至无法加载。 这是一个问题。

除了超重之外,经典框架还具有许多其他缺点,它们并不适合所有项目。 这些问题在“濒临灭绝的框架”中得以解决。 Pavel Malyshev将告诉您,这种新趋势是什么,为什么它不是“另一个JS框架”,而是一个好主意以及神秘的框架如何改善我们的应用程序。
关于演讲者:Pavel Malyshev (
PaulMaly )-全职拥有超过10年的经验。 他在Mustlab工作,该公司将网络,智能电视和移动设备以及物联网外包。 俄罗斯Svelte JS框架的布道者领导了有关此主题的
Telegram小组 。
报告中不应包含的内容
当我考虑这个故事时,我认为它应该是非标准的。 因此,我写了这里不应该写的内容。 将不会强调特定的框架,而不会与其他框架进行比较-它们使每个人都感到厌倦,当然,我不想成为Obvious上尉。 所有这些本不应该出现在我的故事中,但是不幸的是,它将...
读取名称时,您可能会想到还有另一个框架,并且已经有一个完整的动物园。

在我看来,如果出现了一个新框架,那么旧框架将无法满足我们的某些需求。 也许需求本身会随着时间而变化,这就是为什么我们需要新的解决方案-更有效和有趣。 因此,我要求您以开放的态度从上述观点着手解决上述问题,并将消失的框架视为一种可能对您的工作有所帮助的新工具。
首先,让我们弄清楚谁是谁。
谁是谁
我拿了三巨头和斯维尔特。 有趣的是,每个工具的特征都不同。
Angular将自己定位为所有场合的“框架”。
React模仿一个库:“我像一个库一样小”,但是与整个基础架构一起,它也是一个成熟的框架。
Vue应该是一个渐进式框架。 您可以使用jQuery顺序传输代码来切换到它,几乎从没有收集器的常规
script
标签开始。
Svelte是一个神奇消失的框架。 ?
让我们弄清楚我在说什么。
为什么框架开始消失?
我们向用户发送了太多代码。
我们的客户越来越多地移动,但是互联网技术并不是处处都很好-甚至3G也不处处都是,更不用说LTE了。 我们需要减少代码的大小。
2017年有一个
有趣的研究针对此主题,该研究表明,如果您的应用程序包含很多JS,则您可以仅放置
130 Kb来使用户满意 。 如果JS小,则最高可达170Kb。 之所以存在这种差异,是因为该研究考虑到JS与其他类型的资源不同,因此需要对其进行解析,解释等。

在研究中,130 Kb不仅是JS,而且一般来说,包括CSS,HTML在内的所有内容都没有图片。 同时,一个Angular重143 Kb,我们甚至没有编写任何代码行。 让我们看看当前的解决方案为我们提供了什么。
性能表现
原则上,任何经典框架都是对平台的抽象,使我们可以在更方便的级别进行编写。 这是不好的,因为任何抽象都有一些成本,包括性能。
由于我们的代码和浏览器之间不必要的抽象,我们需要支付额外的费用。
框架消失的特征是它们
从浏览器运行时中删除了不必要的抽象和计算,在编译
时执行了分析和计算。 这就是为什么它们消失了。 我们将在下面详细讨论。
相容性
为经典框架编写的解决方案无法应用于任何地方。
它们仅在此框架内工作。 例如,您在自己喜欢的React上做2-3个项目,为其编写了很多很酷的解决方案,然后决定迁移到Angular。 您不再需要这些解决方案;您可以将它们丢弃。 尽管核心思想是组件匹配,但是经典框架使我们无法重用代码。
消失的框架的问题是它们
没有抽象 ,在这种情况下,运行时没有框架。 您的代码绝对是原始JS,可以在任何地方使用-到任何项目,甚至在不同的框架上。 例如,您可以将代码放在消失的框架上,然后将其转移到React。
代码拆分和摇树
旧技术使应用新技术变得困难。
当这些技术不是很发达的时候,大多数框架都是创建的。 我们有一个相当整体的内核,任何组件,甚至是代码的最小部分,都与整个框架相关。 因此,不可能有效地进行代码分割甚至摇树。
现在,所有框架都朝着更大的模块化方向发展,以便更好地“动摇”。 在消失的框架中,这是开箱即用的,因为它们的制作方式是,
仅将您最初需要的代码添加到bundle中 ,并专门解决您的任务。 这是一个非常特殊的情况-就像您完全为任务手动编写代码并将其放入捆绑包一样,只有框架才能为您完成此操作。
功能成本
任何框架都需要为新功能付费。
社区需要不同的新功能,每个成员都需要自己的东西,任何功能都有价。 在消失的框架中,此问题在概念级别上得到了解决,因为您不使用的任何功能都永远不会进入您的捆绑包。
因此,主要问题是:消失的框架(特别是Svelte)能否解决所有这些问题? 让我们做对。
Bez与运行时
Rantime是一个相当短暂的话题。 目前尚不清楚它是什么,并且不同的人对此有不同的理解。 在这种情况下,我将从两个方面来讨论运行时:
执行代码的
环境和
代码本身 。
运行时作为环境
让我们来看一个例子。 如果代码是用Vanilla编写的,那么唯一需要的运行时就是DOM。 如果代码是用React编写的,那么您需要一个不同的运行时:DOM,React和React DOM。
React中代码的最小组成部分将取决于您的框架所处的环境,即运行时。
运行时作为代码执行
第二点是在运行时的代码执行方面的运行时。 让我们用一个简单的示例来看一下当今前端的基本运行时案例-虚拟DOM-例如,在React应用程序中的大量运行时:
<h1>Hello {world}</h1>
在这段HTML中有一个动态变量。 从虚拟DOM的角度来看,代码的工作方式如下。
- 该变量正在被修改。
- 正在构建内存中的虚拟DOM树。
- 与以前的版本相比。
- DOM操作是直接执行的,最终非常有效,因为我们得到了某种差异,并且我们确切地知道在实际DOM中要更改的内容。

虚拟DOM是绝对的开销,因为它总是会这样更快:更改发生后,他们会立即对DOM进行更改。

问题:如何理解发生了什么变化以及需要更改什么? 虚拟DOM解决了更改的问题,而不是更改速度。 之所以能够达到这一速度,是因为我们尽可能了解更改的内容,并且可以有效地操作DOM。
编译它
为了解决这个问题,消失的框架只需在编译阶段确定更改:您在编写代码的过程中,消失的框架将构建所有依赖项,并计算DOM中需要进行哪些操作。 实际上,虚拟DOM在运行时所做的一切,消失的框架在构建时都会做:它会生成与DOM的直接操作,这些操作在运行时会简单地调用。 结果就是一个图表:当我们进行更改时,DOM中的操作马上进行。
您不能在不复杂的情况下用香草JavaScript编写严肃的应用程序。 但是编译器可以为您完成此任务。
Svelte的创始人Rich Harris
我告诉你我是如何遇见斯维尔特的。 我们有一个
有趣的项目 -可以在无数个站点中插入一个小部件,而我们不知道这些站点是什么,用户将在哪些设备上打开它们。 小部件的尺寸应很小,速度应非常快。 自然地,当我们完成这项任务时,我们立即意识到在React甚至Vue上做什么是不可行的,因为这会带来很多额外的开销。
我们几乎倾向于用Vanilla书写,但是维护起来很困难而且并不总是很方便。 但是我们很幸运-我们遇到了斯维尔特。 该框架的主要思想用引号给出:您不能在Vanilla上编写严肃的应用程序,因为您会很快陷入复杂的困境-团队工作将很困难,没有通用的方法,并且编译器可以为您完成。
如何运作
源代码是基于框架的代码 -取决于框架的代码。 一切照常:有一些文档,您编写代码就像使用任何具有某种API,原理和方法的其他框架一样。 一切都和往常一样。
在构建时,此代码会编译。 结果,香草JS位于捆绑包中,并且正如我所说,确切地执行应用程序所需的代码就到达了。 如果在两分钟之内在其中添加另一个新功能或使用框架中的新功能,则Svelte会将其添加到该功能中,并且该功能也将进入捆绑包。 否则将不会发生。
让我们更详细地考虑这些步骤。 第一步是
component 。 考虑相同的组件。
<h1>Hello {world}</h1>
在第二个步骤
AST中 ,代码是在抽象语法树中生成的。
{"type": "Element", "name": "h1", "children": [{ "type": "Text", "data": "Hello",....}]}
第三步是
DOM API 。 在树的基础上,直接生成代码,这对于该组件起作用是必需的。 代码非常简单,原则上这里没有复杂的运行时和抽象。
function update(changed, ctx) { if (changed.name) { text_1.data = ctx.name; } }
在文章的结尾,在调查中指出您是否喜欢Svelte框架的AOT编译的想法?
上一次,多数人发表了积极看法。

现在让我们看看Svelte是什么。
斯维尔特
英语单词svelte或svelt的意思是“苗条,灵活”。 Svelte JS是!
我声称这不是“另一个JS框架”,因为它是一个
构建时UI框架 。 常规框架可在运行时运行,而Svelte仅在我们对其进行编译之前存在。
这是一个
编译时静态分析器 ,或者是一个静态代码分析器,它在编译过程中通过代码,对其进行静态分析,并基于此生成相应的最终包。
这是一个
提前完成的编译器 -可以完成所有工作的AOT编译器。
Rich Harris框架的创建者是一个很酷的家伙,您可以从Rollup,Ractive,Buble(类似于Babel的工具)等工具中了解到。 在我看来,相同的汇总仍然是最好的摇树实现。 它出现在Webpack中的时间要早得多,但效果仍然更好。 哈里斯最初用摇树,代码拆分和其他现代方法构建了Svelte框架。
Svelte是编写香草JS的工具,而无需编写香草JS。
让我们从内部看一下这个框架。
单个文件组件
Svelte是一个单文件组件 。 如果您使用Vue,它将使您非常想起这个框架,但这绝非偶然。 Vue主要使用的语法源自Ractive框架,Harris早在2012年就采用了该框架。 不幸的是,在我看来,该框架并未流行,因为它在1.0中发布得太晚了。 他们对这些版本感到很困惑,以至于Ractive在次要版本中使用了6年。
Vue从那里借来了许多接口,而Svelte是Ractive的后继者。 因此,在您看来一切都相似,但是单文件组件在2013年出现在Ractive中。 它们看起来有些不同,但总体而言-看起来很像。 您在Svelte中编写的任何组件都将如下所示。
<h1 >Hello {world}!</h1 > <script> export default { /* component behaviour */ }; </script> <style> /* scoped styles */ </style>
上面是某些HTML模板-纯HTML,没有任何例外。 最重要的是一种称为
HTMLx的模板语言。 待会儿我再告诉你有关他的更多信息。
接下来是脚本,我们在其中编写组件的行为。 指南中描述了如何编写。 您可以在那里导入,制作各种功能和方法-就像在Vue中一样。
您可以使用作用域样式从框中获取隔离的组件样式。 它的工作方式是这样的:在主编译中,将生成一个哈希,结果就像模拟Shadow DOM。
不需要任何部分,因此一个组件只能包含一个HTML。
HTMLx语法
与任何HTML一样,数据写在方括号中。
<button>Say hello {name}</button>
这就是条件语句的编写方式。
{#if name} <button>Say hello {name}</button> {/if}
枚举和循环:
{#each users as { name, email}} {#if name} <button>Say hello {name}</button> {/if} {/each}
您可以使用指令来捕获事件,以进行双重数据绑定。
{#each users as { name, email}} {#if name} <button on:click="say(name)">Say hello {name}<button> {/if} {/each}
HTMLx中的指令很少-只有4-5种,并且没有自定义指令,例如Angular。
您可以将任何动态数据推入任何属性,这没有问题。
<div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div>
孤立的样式和未使用的样式
如果使用隔离样式,则除了隔离以外,未使用的样式也会自动剪切。
<div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div> </style> .used {...} .unused {...} </style>
如果使用样式,则使用样式;如果样式
unused
,则它将不在捆绑包中。 该框架将精简所有内容。 因此,如果您使用大量动态特性,则可以轻松破坏此功能。 斯维尔特会想:“我最好不要碰”-然后离开。 必须小心,但这非常方便。 由于Svelte具有静态分析器,因此它会在启动时在控制台中显示未使用的样式。 如果确实不需要它们,则可以立即将其删除。
成分组成
一切都和这里一样:我们导入文件,将其注册在组件中,并将其用作标签。
<Nested foo= "static" bar={dynamic} bind:baz=baz /> <script> import Nested from 'Nested.html';' export default { components: {Nested} }; </script>
您可以通过属性传输任何数据,使用双重绑定。 还是不使用-双重绑定是可选的,甚至可以在编译器级别禁用它,并且在其他任何地方都不会使用。 这是给那些不喜欢绑定的人使用的。 使用
bind:
指令获得
bind:
。
Svelte的其他功能
前两种可能性是:
SSR和水化 -服务器渲染和水化,以及
内置状态管理 -基于我们自己的解决方案(即所谓的商店)的内置全局状态管理。
原则上,您可以使用Redux,很多人都可以使用它:那些习惯Redux的人将其与Svelte一起使用。 但是,有一个更简单的内部解决方案已深度集成,因此,如果您在商店中注册它,则该解决方案可立即在所有组件层次结构中使用-完全无需任何操作。 唯一要使用的就是使用
$
前缀,即所有方法或存储数据都使用该前缀编写。
$
可以在任何模板中使用。
该商店具有一个有趣的功能,我在其他任何地方都没有看到过-它在全球范围内扩展到一个组件层次。 例如,如果您具有Root组件,则会在整个层次结构中使用它。 如果您在此层次结构内的某处有另一个商店,则此商店将扩展到整个较低的层次结构。
当您要制作一个包含许多子组件的大型复杂组件,然后在不同的项目中使用该项目时,这很方便,在某些项目中有Redux,而在其他项目中则没有。 如果将常规存储与Redux一起使用,则需要确保添加该项目的项目具有Redux。 此处不需要这样做-Svelte为此层次结构实现了自己的存储。 甚至可以将其轻松转移到根本没有全球存储的项目中。 您带来了它,而Svelte已经在做内部的所有事情。
开箱即用地支持自定义元素 。 有一个
特殊的站点 ,其上的支持由Web Components标准的框架进行测试。 根据测试,Svelte 100%支持自定义元素。 它的工作方式是这样的:指定标签名称,在编译器中设置“ customElement:true”标志,并生成一个准备使用的自定义元素,该元素支持所有现有的Svelte功能。
Sapper-Svelte应用程序制造商 。 这是Vue的Next.js和Nuxt.js的类似物。 原则上,所有内容都是相同的:同构,对代码拆分,预取和脱机支持以及其他功能。 我认为,最近路由的一些想法也从Sapper到Next.js。
但是没有一个斯维尔特能做到这一点。 我们是为了公平竞争!
还有谁
Stencil是Ionic开发人员的框架。 它们还可以在已编译的框架上工作,但主要关注Web组件和自定义元素。 Svelte与它的不同之处在于,它的组件通常被编译为常规JS类,并且Web组件没有偏见。
微光 -我想每个人都知道这个项目。 之所以在这里展示它,是因为它也可以编译:它具有自己的字节码,自己的虚拟机,显然,它为最终代码提供了其他优化。
来自eBay的Marko 。 我还没有详细研究它,但是它们也可以编译,不确定是否像Svelte一样深入。 是的,我没有详细了解,可能是错误的。
角度的 这里有一个AOT编译器,它会得到很好的推广,但这只是预先以现成的排序形式重新编译字符串模板。 据我了解,目前还没有完整的AoT编译。
你好电影
我编写了一个小应用程序-带有基于TMDb API的滤镜的电影列表。 它具有类别:流行,最高评分,即将到来。 您可以在页面上四处走动,选择一个国家,为其应用过滤器,更改语言。 此原始应用程序仅占用6.4 Kb。
HELLO MOVIES总共只有172行代码以及HTML,其中36行JS代码以及各种引号。 这就是我亲自编写的所有代码。 当然,所有这些都可以编译成更大的体积,但是对我来说,作为开发人员,这并不重要。
还有一些指标。 Svelte上的“ TodoList MVC”需要3.6 Kb-取决于说谁,但即使在Vanilla上也需要11 Kb,在Vue和React上甚至分别需要80 Kb和300 Kb。 “ RealWorld”项目是Medium的一个副本,具有React,Angular上的注册,帐户,喜欢,共享,朋友-40 Kb-211和575 Kb。 在Svelte上,“ HackerNews”的副本在React和Vue上是30 Kb-几倍。
基准测试
我们都喜欢基准测试主题的hollichivat。 我使用了著名的
Krausest基准测试。 您可能以为我现在将显示结果,其中斯维尔特(Svelte)只是将所有人撕成碎片,而地狱(Inferno)则哭到一边。 但这不会发生。

我将Svelte与三大版本-Angular,React和Vue进行了比较。 结果,他确定了有关香草的前两个职位。 这里的数字并不像主要思想那么重要,那就是
斯维尔特非常平衡 。
斯维尔特努力做到平衡-
在任何基准方面都很好 。 在某些方面,斯维尔特甚至超过了香草,在某些方面它超过了香草,但在某些地方却超过了Vue和Angular。 但是,在所有测试中,Angular和Vue会占用大量内存,而Svelte不会。 , , . — .
Svelte — . , .
- — !
Svelte New York Times. . , Svelte, , legacy- CMS, . , , .

,
- « » — , Drag&Drop. Svelte, .
Soft-Gear , , Svelte. , - .
airca.st Svelte.
Dabble Svelte. -
i-want-to-ride-an-electric-citi Svelte.
. , RuTube. Smart TV Tizen, Samsung. Tizen Smart TV Svelte. , .
standalone vanilla JavaScript . , , overhead .
. Svelte DOM. .
. , Vue, Svelte .
,
REPL , , .
. , — , . , .
Code-splitting & tree-shaking . code-splitting tree-shaking. . , .
Micro-frontends ready . -. , , PHP, Svelte-. , . , . code-splitting tree-shaking.
Svelte , . 2016 . .
. , . . , , , , , Vue.
. React Facebook, Angular — Google, Vue , Rich Harris , .
Frontend Conf ++ , , . 33 . ++ 27 28 .