最近这些年,随着React、Vue、Angular三大框架逐渐稳定,前端技术栈的迭代似乎也渐渐缓慢下来。并且随着React 16版本推出 Fiber, Vue 3.0 版本的正式发布,前端三大框架都有了自己的护城河。

不过话说回来,十年前我们谁会想到前端也会自成一派,变得如此智能。试想一下,如果我们把目光拉伸到未来十年,前端行业会出现怎么样的发展呢,会不会有挑战React或者Vue的新技术出现呢? 对于未来的发展,或许我们无从知晓,但是我们今天给大家推荐的Svelte 或许会是一个不错的挑战者。

一、Svelte简介

Svelte是一个新兴的热门前端框架,作者是 Rich Harris,被称为前端界的【轮子哥】,有Ractive、Rollup 和 Buble开源作品。

在官方的介绍中,Svelte 即是一个前端 UI框架,同时也是一个 编译器。在《State of JS survey of 2020》报告中,它被预测为未来十年可能取代React和Vue等其他框架的新兴技术。在开源托管网站Github上,Svelte也获得了超过61k的关注,这仅次于明星框架React和Vue。

在最新的开发者感兴趣的前端框架中,Svelte更是超过传统的知名框架Vue和React,排在第一位。

不过,这倒并不是说Svelte有多厉害,因为Svelte 当前仍是一个小众的开发框架,市场占有率方面也仍小于React和Vue,不过进步是特别明显的。

二、Svelte的优点

事实上,作为一个前端框架,Svelte在语法、使用体验上没有什么特别之处。真正不同的地方,是Svelte对前端AOT(ahead-of-time,可以理解为预编译)的探索。

如果大家对React、Vue 的设计思路比较了解的话就会知道,他们必须引入运行时 (runtime) 代码,用于虚拟dom、diff 算法。而Svelte 的设计思路是【通过静态编译减少框架运行时的代码量,即预编译】,Svelted完全溶入JavaScript,应用所有需要的运行时代码都包含在bundle.js里面,因此不需要额外在引入运行时。

2.1 No Runtime

React 和 Vue 都是基于运行时的框架,当用户操作页面进行各种操作改变组件的状态时,框架的运行时会根据组件状态(state)计算(diff)出哪些DOM节点需要被更新,从而更新视图。这就意味着,基于运行时框架本身所依赖的代码也会被打包到最终的构建产物中,结果是不可避免增加了打包后的体积。下图是常见的前端框架运行时的大小。

可以看到,最小的Vue有58k、React则有97.5k。 所以,如果我们如果使用React开发一个小型组件,即使里面的逻辑代码很少,但是打包出来的bundle size也会超过100k。对于大型后台管理系统来说100k 不算什么,但是对于特别注重用户端加载性能的场景来说,一个组件已经足够大了。

下面是Jacek Schae大神使用市面上主流的框架编写同样的Realword 应用,然后最终打包发布的体积。

可以看到,Svelte的bundle包的大小是Vue的1/4,React的1/20,体积上的优势还是相当明显的。

2.2 Less-Code

并且,编写同样的组件时,和 Vue 、React相比,Svelte只需要更少的代码。比如,React 官方的加法的示例代码:

//React
const [count, setCount] = useState(0);
function increment() {setCount(count + 1);
}

而如果使用Svelte来实现的话,代码量明显变少。这是因为Svelte可以直接使用赋值操作符更新组件的状态。

//Svelte
let count = 0;
function increment() {count += 1;
}

如果说上面的例子太简单了,不足以看出效果。那么下面还是使用Jacek Schae 编写Realword 应用代码行数的统计来说明。

2.3 Hight-Performance

在Virtual Dom已经是前端框架标配的今天, Svelte 声称自己是没有使用Virtual Dom, 那他是怎么还能保证高性能的呢?

下面是Jacek Schae 在《A RealWorld Comparison of Front-End Frameworks with Benchmarks》一文中使用主流的前端框架来编写 RealWorld 应用,使用 Chrome 的Lighthouse Audit测试性能,得出数据是Svelte 略逊于Vue,但好于 React。

而使用 JavaScript Framework Benchmark工具来分析各个框架的执行时间、内存占用及启用时间也给出了同样的答案。

在执行速度的方面,经过多次测试,Svelte 速度最快,Vue 紧随其后,React 和 Angular 速度较慢。

而在内存占用方面,Svelte 仍然保持大幅度领先,Vue 略微优于并驾齐驱的 React 和 Angular。

在启动方面,Svelte 的启动速度也非常出色,Vue 略逊一筹,React 和 Angular 紧随其后。 可以看到,在性能方面,Svelte并不逊色其他框架。

三、Svelte的缺点

当然,作为一个尚处在起步阶段的框架,Svelte 还有很多的不足,如果是在大型的商业项目中中使用 , 需要特别的谨慎。例如,下面是不同策略对代码生成量的影响。

根据尤大的测试,Svelte 是通过生成命令式的一个一个节点,然后把节点拼接这些 Javascript 代码。那这个策略就导致同等的这个组件源码之下 Svelte 每个组件的编译输出会更臃肿。虽然大家会第一印象是觉得说 Svelte 是以轻量而出名的,但其实我们会发现,在相对大型的项目中,在项目中组件超过 15 个之后,Svelte 的整体的打包体积优势就已经几乎已不存在。

除此之外,Svelte的缺点还包括:没有像AntD那样成熟的UI库。不支持预处理器,比如说less/scss,需要自己单独的配置 webpack loader等。不过,可以看到,Svelte正在快速的更新,最新版本解决的问题也不少。

四、快速上手

4.1 创建项目

和其他前端框架一样,创建一个Svelte项目是非常简单的,命令如下。

npm create svelte@latest my-app
cd my-app
npm install
npm run dev

然后在浏览器中打开 http://localhost:5173/ 就能访问对应的页面,运行的效果如下图。

如果需要修改端口号,可以打开package.json 文件,然后在启动命令里修改环境变量 PORT。

"scripts": {"dev": "PORT=4000 rollup -c -w",
},

4.2 less配置

创建Svelte项目的时候,模板本身是不携带任何插件的,如果需要在 Svelte 组件中写 less,需要安装相关的依赖。

npm install svelte-preprocess-less less

然后,在 rollup.config.js 中添加相关的配置,如果没有 rollup.config.js 文件,可以新建一个。

import sveltePreprocess from 'svelte-preprocess';
import { less as svelteLess } from 'svelte-preprocess-less';
export default {plugins: [svelte({preprocess: sveltePreprocess({style: svelteLess(),}),}),],
};

接下来,我们就可以在组件中的

 <style lang="less"> ...</style>

五、语法基础

5.1 基本用法

在Svelte应用中,一个.svelte就是一个组件,它由html、css和js代码组成,类似vue的写法。其中,

<script>let src = 'image.gif';let name = 'Rick Astley';
</script>
<img {src} alt="{name} dances.">

当属性名和变量名是一样的时候,我们也可以简写省略掉变量名。而样式,和其他的写法是一样的。

<style>.counter {display: flex;border-top: 1px solid rgba(0, 0, 0, 0.1);border-bottom: 1px solid rgba(0, 0, 0, 0.1);margin: 1rem 0;}
</style>

不过,上面说的例子都是简单的一个小组件,对于一个完整的应用程序来说,必然是由多个组件构成的。和其他的框架一样,使用时需要import引入进来,不同之处在于,import需要写在

<script>import Counter from '$lib/Counter.svelte';
</script><section><Counter />
</section>

5.2 响应式

响应式也是Svelte的核心特性之一,在js里直接修改绑定的变量,就可以同步看到DOM上数据的改变。

<script>let count = 0;function handleClick() {count++;}
</script>
<button on:click={handleClick}>Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

类似vue里的computed,这里叫【反应式声明】,这样写:

let count = 0;
$: doubled = count * 2;

然后,就可以在众像用count那样使用doubled。Svelet的响应式是有赋值语句触发的,所以像数组的push、splice这些操作就不会触发更新,正确的做法是需要手动添加一个看似多余的赋值语句,比如。

<script>let numbers = [1, 2, 3, 4];function addNumber() {numbers.push(numbers.length + 1);numbers = numbers;// 或者写成// numbers = [...numbers, numbers.length + 1];}$: sum = numbers.reduce((t, n) => t + n, 0);
</script>
<p>{numbers.join(' + ')} = {sum}</p>
<button on:click={addNumber}>Add a number
</button>

5.3 属性传值

在前端框架中,组件之间的传值一般使用的是构造函数。在Svelte中,组件之间的传值也比较简单,不过需要额外在子组件里,使用export关键字将值传递出去。

<Nested answer={21}/>//子组件使用export导出
<script>export let answer;
</script>
<p>The answer is {answer}</p>

5.4 逻辑语句

和其他的框架不同,Svelte的逻辑语句需要在HTML里面处理,比如{#if xxxxx},语法方面感觉比不是很友好。

{#if user.loggedIn}<button on:click={toggle}>Log out</button>
{/if}

而对于if-else的写法,如下。

{#if x > 10}<p>{x} is greater than 10</p>
{:else if 5 > x}<p>{x} is less than 5</p>
{:else}<p>{x} is between 5 and 10</p>
{/if}

其中,#表示一个块逻辑的开始,/表示结束,:表示继续。

如果要进行循环,一般使用的是for/each。不过,Svelte的循环语句实在让人难以接受。

<script>let cats = [{ id: 'J_aiyznGQ', name: 'Keyboard Cat' },{ id: 'z_AbfPXTKms', name: 'Maru' },];
</script>
<h1>The Famous Cats of YouTube</h1>
<ul>{#each cats as cat,index}<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">{index+1} {cat.name}</a></li>{/each}
</ul>

5.5 事件

和其他框架一样,Svelte提供了on:click,on:mousemove等指令来监听事件。

<button on:click={() => (count += 1)} aria-label="Increase the counter by one"><svg aria-hidden="true" viewBox="0 0 1 1"><path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" /></svg>
</button>

当然,事件监听的时候也可以使用事件修饰符,用‘|’分隔,表示可以连续使用多个。

on:click|once|capture={handleEvent}

特别需要注意的一点是,如果子组件内部想要接受父组件的点击事件,只需要在子组件内部加上on:click即可。

//父组件
<script>import FancyButton from './FancyButton.svelte';function handleClick() {alert('clicked');}
</script>
<FancyButton on:click={handleClick}/>//子组件
<button on:click>Click me
</button>

5.6 事件绑定

Svelte里的数据绑定和Vue、React时类似的,使用的是bind:value方式进行绑定。例如,下面是input标签的事件绑定。

<script>let name = 'world';
</script>
<input bind:value={name}>
<h1>Hello {name}!</h1>

上述是单个值的绑定,那么绑定多个值的时候,可以用bind:group将value放在一起。

<label><input type=checkbox bind:group={flavours} value={flavour}>
</label>

并且,bind:this可以绑定任何标签或者组件,并且可以获得标签的引用,类似于React的ref。

<canvasbind:this={canvas}width={32}height={32}
></canvas>onMount(() => {const ctx = canvas.getContext('2d');.....
}

组件的属性也可以绑定,比如在父组件引用子组件的属性。

<Keypad bind:value={pin} on:submit={handleSubmit}/>

不过,作为一款年轻的前端框架,很少能够看到一些互联网公司将 Svelte 应用于生产,究其原因,无外乎以下几点:

  • 对低端手机支持不太友好,特别是用shadow等高级特性。
  • 生态不是很完善,配套的安全、性能测试、自动化等工具不是很完善。
  • 全新的语法,需要一定的学习成本。

参考:

携程机票前端Svelte生产实践

Svelte3聊天室|svelte+svelteKit仿微信聊天实例|svelte.js开发App

基于Svelte3+SvelteKit+Sass仿微信Mac界面聊天实战项目

前端Svelte框架初体验相关推荐

  1. 【Flask框架】一. Flask框架初体验(配置环境 + 简单demo样例)

    文章目录 一. Flask框架初体验(配置环境 + 简单demo样例) 虚拟环境 新建项目 将Pycharm改为FLASK_DEBUG模式 修改FLASK_DEBUG模式的步骤 配置文件 简单用法 U ...

  2. python的scrapy爬虫模块间进行传参_小猪的Python学习之旅 —— 4.Scrapy爬虫框架初体验...

    小猪的Python学习之旅 -- 4.Scrapy爬虫框架初体验 Python 引言: 经过前面两节的学习,我们学会了使用urllib去模拟请求,使用 Beautiful Soup和正则表达式来处理网 ...

  3. 自然语言处理NLP星空智能对话机器人系列:Facebook StarSpace框架初体验

    自然语言处理NLP星空智能对话机器人系列:Facebook StarSpace框架初体验 目录 Facebook StarSpace github StarSpace 安装部署 编译星际空间 Face ...

  4. A-Frame WEB VR框架初体验

    aFrame是一个Web VR框架,底层是基于threejs的,刚好项目也用到了threejs,就用aFrame试了下效果.在网页上看起来,aFrame就是把threejs的的实现包装成一个实体标签. ...

  5. Vue3系列(二)之安装依赖与UI框架初体验

    目录 一.安装常用依赖 二.UI框架体验 1.Element-plus 1.1 完整引入 1.2 按需引入 1.3 国际化 - 中文 2.Ant-Design 2.x 2.1 完整引入 2.2 按需引 ...

  6. 爬虫Scrapy框架初体验

    目录结构: |写在前面: |依葫芦画瓢: |       | 安装: |       | 概述: |       | 创建一个scrapy项目 |       | 第一个scrapy蜘蛛 |      ...

  7. Scrapy 爬虫框架初体验二 —— 以一个新闻站点爬取为例

    一.搭建基础 Scrapy 工程框架 创建项目 输入如下命令: scrapy startproject NewsSpider # 创建项目 cd NewsSpider scrapy genspider ...

  8. Python3 - Flask框架初体验(第六天)

    文章目录 1.Flask安装 2.项目架构 3.路由及重定向 4.实例用法 1.Flask安装 pip install flask --- 写项目的框架 pip install flask-scrip ...

  9. 《慕客网:IOS基础入门之Foundation框架初体验》学习笔记 三 NSArray

    2019独角兽企业重金招聘Python工程师标准>>> 1 int main(int argc, const char * argv[]) { 2 @autoreleasepool ...

  10. 《慕客网:IOS基础入门之Foundation框架初体验》学习笔记 五 NSDicionary + NSMutableDictionary...

    2019独角兽企业重金招聘Python工程师标准>>> 1 int main(int argc, const char * argv[]) { 2 @autoreleasepool ...

最新文章

  1. python 并行计算 并行方法总结 concurrent.futures pp pathos multiprocessing multiprocess模块 总结对比
  2. js如何打印object对象
  3. 蓝桥杯 如何计算 X^X = 10 来求X呢?
  4. Mongodb基础实践(二)
  5. jquery实现的3D缩略图悬停效果
  6. ASP.NET Core在Azure Kubernetes Service中的部署和管理
  7. enum与int、String之间的转换
  8. linux 卸载 patch,Oracle RAC 平台下 Patch 安装与卸载 步骤 收藏
  9. 买手机,是不是运行内存大,手机用久了也不卡?
  10. C# DateTime类
  11. 88上的数学题目之二
  12. CATIA二次开发—遍历结构树
  13. linux 强制结束任务管理器,结束拒绝访问的进程 cmd下结束进程 强行结束进程
  14. 读科研经费陷“无底黑洞”有感
  15. 超全Redis命令总结(备忘)(建议赶紧收藏)
  16. javaweb-linux-44
  17. 掉头发最该补的东西竟然是它?99%的人都不知道!
  18. C语言:sizeof()和countof()
  19. linux usb音频,audio - 如何从linux USB捕获设备捕获与ffmpeg同步的音频和视频 - 堆栈内存溢出...
  20. 联想520r服务器装系统,联想Miix520本地模式重装win7系统教程

热门文章

  1. linux编译webengine,am3352请问如何在linux3.8上移植带有webengine的qt5?
  2. Dell 电脑重装系统步骤(一)
  3. PyTorch读取目标检测数据集
  4. Python小程序(4)--52周存钱挑战
  5. latex----目录格式设置
  6. 数据分析:单元3 图像的手绘效果实现
  7. dota2服务器切换账号,DOTA2怎么改成国服 教你三步完成设置
  8. 备案修改域名服务器DNS,免备案域名的DNS改到dnspod教程详解
  9. 一起学爬虫(Python) — 05
  10. 3个国内最大的黑客学习网站