黑马程序员技术交流社区

标题: 【西安校区】谈谈新的前端框架 Svelte 和现代前端框架的特点 [打印本页]

作者: 逆风TO    时间: 2020-5-11 11:01
标题: 【西安校区】谈谈新的前端框架 Svelte 和现代前端框架的特点
官方网址
https://svelte.dev/

这个框架还是非常不错的,轻量级,代码量少,没有Virtual DOM高性能,涵盖了非常多的优点。

先来说说轻量级,通过CSS缩小后有约17kb的大小,gzip后更是小到了4kb,可以说是比3大前端框架都小。
代码量少,Svelte直接免去了类和对象的编写,使用Svelte写代码省去30%-40%的代码量。

Svelte 的代码长什么样子呢?
[Java] 纯文本查看 复制代码
<script>
        let count = 0;
        $: doubled = count * 2;

        function handleClick() {
                count += 1;
        }
</script>

<button on:click={handleClick}>
        Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

有过前端开发经验的朋友第一眼看到这段代码肯定会问,这个 $: 是什么玩意?

其实这个就是相当于Vue中的computed的意思,React的useMemo() 的意思。是不是看上去很简洁?

Svelte的编译器会把这一段代码编译成以下代码,然后再通过webpack编译打包。
细心对比编译前后的代码,我们可以看出Svelte设计的巧妙之处。

import 语句,类声明和export语句是Svelte编译器之后加上的,节约了你去写这些代码的时间。同时因为没有类或对象的编写过程,节约了写this关键字。
编译好的create_fragment方法是用来生成DOM目录树的,它是直接将源代码的html模板编译成了代码去实现响应式变化,最终这个新生成的节点会直接使用到真DOM上,这就是它宣传的没有Virtual DOM和它高性能的原因(因为有了Virtual DOM,还要做Diff之类的算法去做比对)。
Svelte框架在webpack打包前就编译好了纯原生JS库就可以执行代码,它的运行库不用再对类似于计算属性的内容再做额外的库和运算,所以它编译出来的包很小,执行效率也更高。也正因如此,Svelte的打包不再区分dev和prod模式,保证了生产环境和最终产品包的一致性。
[Java] 纯文本查看 复制代码
/* App.svelte generated by Svelte v3.22.2 */
import {
        SvelteComponent,
        append,
        detach,
        element,
        init,
        insert,
        listen,
        noop,
        safe_not_equal,
        set_data,
        space,
        text
} from "svelte/internal";

function create_fragment(ctx) {
        let button;
        let t0;
        let t1;
        let t2;
        let t3_value = (/*count*/ ctx[0] === 1 ? "time" : "times") + "";
        let t3;
        let t4;
        let p;
        let t5;
        let t6;
        let t7;
        let dispose;

        return {
                c() {
                        button = element("button");
                        t0 = text("Clicked ");
                        t1 = text(/*count*/ ctx[0]);
                        t2 = space();
                        t3 = text(t3_value);
                        t4 = space();
                        p = element("p");
                        t5 = text(/*count*/ ctx[0]);
                        t6 = text(" doubled is ");
                        t7 = text(/*doubled*/ ctx[1]);
                },
                m(target, anchor, remount) {
                        insert(target, button, anchor);
                        append(button, t0);
                        append(button, t1);
                        append(button, t2);
                        append(button, t3);
                        insert(target, t4, anchor);
                        insert(target, p, anchor);
                        append(p, t5);
                        append(p, t6);
                        append(p, t7);
                        if (remount) dispose();
                        dispose = listen(button, "click", /*handleClick*/ ctx[2]);
                },
                p(ctx, [dirty]) {
                        if (dirty & /*count*/ 1) set_data(t1, /*count*/ ctx[0]);
                        if (dirty & /*count*/ 1 && t3_value !== (t3_value = (/*count*/ ctx[0] === 1 ? "time" : "times") + "")) set_data(t3, t3_value);
                        if (dirty & /*count*/ 1) set_data(t5, /*count*/ ctx[0]);
                        if (dirty & /*doubled*/ 2) set_data(t7, /*doubled*/ ctx[1]);
                },
                i: noop,
                o: noop,
                d(detaching) {
                        if (detaching) detach(button);
                        if (detaching) detach(t4);
                        if (detaching) detach(p);
                        dispose();
                }
        };
}

function instance($$self, $$props, $$invalidate) {
        let count = 0;

        function handleClick() {
                $$invalidate(0, count += 1);
        }

        let doubled;

        $$self.$$.update = () => {
                if ($$self.$$.dirty & /*count*/ 1) {
                        $: $$invalidate(1, doubled = count * 2);
                }
        };

        return [count, doubled, handleClick];
}

class App extends SvelteComponent {
        constructor(options) {
                super();
                init(this, options, instance, create_fragment, safe_not_equal, {});
        }
}

export default App;

Svelte还在发展,目前的缺点也很明显,就是官方还不支持TypeScript,官方还不支持路由,扩展库不多。

对于这种结构编译型的框架,我觉得会是前端框架发展的方向。
因为要做代码结构转换,多支持TypeScript会比其他3大框架的工作量多得多,我想这也是为什么官方迟迟没有退出的原因。

现代前端框架发展至今,本文我还想总结出他们共性。

转自CSDN:https://blog.csdn.net/weixin_36330664/article/details/106022804






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2