• 前端Svelte框架初体验


    最近这些年,随着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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    //Svelte
    let count = 0;
    function increment() {
      count += 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果说上面的例子太简单了,不足以看出效果。那么下面还是使用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。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7afO7KwT-1658977170654)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5bcda28987a04c008e556fbdc654ef33~tplv-k3u1fbpfcp-watermark.image?)]

    在启动方面,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
    
    • 1
    • 2
    • 3
    • 4

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

    在这里插入图片描述

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

    "scripts": {
      "dev": "PORT=4000 rollup -c -w",
    },
    
    • 1
    • 2
    • 3

    4.2 less配置

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

    npm install svelte-preprocess-less less
    
    • 1

    然后,在 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(),
             }),
          }),
       ],
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

     
    
    • 1
    • 2
    • 3

    五、语法基础

    5.1 基本用法

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

    
    {name} dances.
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5.2 响应式

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

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

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

    
    

    {numbers.join(' + ')} = {sum}

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.3 属性传值

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

    
    
    
    //子组件使用export导出
    
    

    The answer is {answer}

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.4 逻辑语句

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

    {#if user.loggedIn}
       
    {/if}
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    {#if x > 10}
        

    {x} is greater than 10

    {:else if 5 > x}

    {x} is less than 5

    {:else}

    {x} is between 5 and 10

    {/if}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

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

    
    

    The Famous Cats of YouTube

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.5 事件

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

    
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    on:click|once|capture={handleEvent}
    
    • 1

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

    //父组件
    
    
    
    
    //子组件
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.6 事件绑定

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

    
    
    

    Hello {name}!

    • 1
    • 2
    • 3
    • 4
    • 5

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

    
    
    • 1
    • 2
    • 3

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

    
    
    
     
    onMount(() => {
      const ctx = canvas.getContext('2d');
      .....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    
    
    • 1

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

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

    参考:

    携程机票前端Svelte生产实践

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

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

  • 相关阅读:
    激光雕刻机的雕刻操作
    虾皮网同行数据丨虾皮数据工具-知虾:监控竞争对手数据的利器
    Charles如何抓取https请求-移动端+PC端,学完不要去做坏事哦
    顺序表与链表(上)
    Day22:多态详解
    定制音库成本骤降98%,PaddleSpeech小样本语音合成方案重磅来袭!
    RK3399 Android10 移除应用权限(包含USB)申请弹框
    肩胛骨筋膜炎怎么治疗最有效
    【微信小程序】解决分页this.setData数据量太大的限制问题
    CICD 流程学习(四)搜素服务与消息队列
  • 原文地址:https://blog.csdn.net/xiangzhihong8/article/details/126030399