首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SvelteJS与ReactJS呈现差异(重绘/再流)

SvelteJS与ReactJS呈现差异(重绘/再流)
EN

Stack Overflow用户
提问于 2019-11-17 16:02:52
回答 2查看 762关注 0票数 3

以下是我对DOM和浏览器如何工作的天真理解

每当DOM (真正的DOM )中的某些内容发生更改时,浏览器都会重新绘制或重新绘制dom。因此,在每次DOM更改浏览器需要重新计算CSS、执行布局和重新绘制网页时,都会使用更简单的术语。这才是真正需要时间的地方。

因此,React与这个虚拟DOM一起出现,它实际上所做的是对更改进行批处理,并一次调用将它们应用到real上。因此,尽量减少回流和再油漆。

那斯维特呢。如果它直接操作DOM,那么它如何控制浏览器的重绘/再流。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-26 08:45:33

除了上面(正确的)答案: Svelte“编译”您提供给它的代码,所以最终的代码可以在没有库运行时(与React相反)的情况下执行。它创建了相当可读的代码,因此绝对有可能理解内部工作。

注:这将是一个较长的答案-仍然遗漏了许多分钟的细节是什么下正在发生的罩下的斯维特。但我希望它能帮助揭开一些隐藏在引擎盖下的东西。另外,这也是Svelte在3.16.x版本时所做的事情。因为这是内部的,它可能会改变。然而,我仍然发现了解到底发生了什么是值得的。

所以,我们开始吧。

首先也是最重要的: Svelte教程有一个有用的特性,可以让您看到生成的代码(就在“结果”窗格旁边)。一开始它看起来有点吓人,但你很快就掌握了它的诀窍。

下面的代码将基于此示例(但进一步简化):Svelte教程-反应性/作业

我们的示例组件定义(即App.svelte)如下所示:

代码语言:javascript
复制
<script>
    let count = 0;

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

<button on:click={handleClick}>{count}</button>

基于这个组件定义,Svelte编译器创建一个函数,该函数将创建一个“片段”,该“片段”接收“上下文”并与之交互。

代码语言:javascript
复制
function create_fragment(ctx) {
    let button;
    let t;
    let dispose;

    return {
        c() {
            button = element("button");
            t = text(/*count*/ ctx[0]);
            dispose = listen(button, "click", /*handleClick*/ ctx[1]);
        },
        m(target, anchor) {
            insert(target, button, anchor);
            append(button, t);
        },
        p(ctx, [dirty]) {
            if (dirty & /*count*/ 1) set_data(t, /*count*/ ctx[0]);
        },
        i: noop,
        o: noop,
        d(detaching) {
            if (detaching) detach(button);
            dispose();
        }
    };
}

片段负责与DOM交互,并将与组件实例传递。简而言之,里面的代码

  • "c“将在create上运行(在内存中创建DOM元素并设置事件处理程序)
  • "m“将在挂载上运行(将元素附加到DOM)
  • "p“将在update上运行,即当某些东西(包括道具)发生变化时
  • "i“/ "o”与入门/outro(即过渡)相关。
  • "d“将运行在销毁上。

注意:像element或set_data这样的函数实际上是非常容易理解的。例如,函数元素只是document.createElement的包装器。

代码语言:javascript
复制
function element(name) {
    return document.createElement(name);
}

context (ctx)将保存所有实例变量以及函数。它不过是一个简单的数组。由于Svelte“知道”每个索引在编译时的含义,所以它可以在其他地方对索引进行硬引用。

此代码本质上定义了实例上下文:

代码语言:javascript
复制
function instance($$self, $$props, $$invalidate) {
    let count = 0;

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

    return [count, handleClick];
}

实例方法和create_fragment都将从另一个函数调用init调用。它涉及得更多,所以您可以看看这个链接到源,而不是在这里复制和粘贴它。

$$invalidate将确保计数变量设置为脏,并安排更新。当下一个更新运行时,它将查看所有“脏”组件并更新它们。这是如何发生的,实际上更多的是实现细节。如果感兴趣,请在冲洗功能中设置一个断点。

事实上,如果您真的想更进一步,我建议克隆模板应用程序,然后创建一个简单的组件,编译它,然后检查"bundle.js“。如果删除源代码映射或禁用它们,也可以调试实际代码。

因此,例如,将rollup.config.js设置为:

代码语言:javascript
复制
    output: {
        sourcemap: false,
        format: 'iife',
        name: 'app',
        file: 'public/build/bundle.js'
    },
    plugins: [
        svelte({
            dev: false,

注意:如上所示,我建议也将dev模式设置为false,因为这将创建更简洁的代码。

一个很好的特性:一旦我们的应用程序运行,您也可以访问app变量(它被分配给全局窗口对象,因为它被捆绑为一个立即调用的函数表达式)。

所以,你可以打开你的控制台,简单地说

代码语言:javascript
复制
console.dir(app)

会产生这样的东西

代码语言:javascript
复制
App
    $$:  
        fragment: {c: ƒ, m: ƒ, p: ƒ, i: ƒ, o: ƒ, …}
        ctx: (2) [0, ƒ]
        props: {count: 0}
        update: ƒ noop()
        not_equal: ƒ safe_not_equal(a, b)
        bound: {}
        on_mount: []
        on_destroy: []
        before_update: []
        after_update: []
        context: Map(0) {}
        callbacks: {}
        dirty: [-1]
        __proto__: Object
    $set: $$props => {…}

一个很酷的特性是,您可以自己使用$set方法来更新实例。例如:

代码语言:javascript
复制
app.$set({count: 10})

也有Svelte DevTools试图使斯维特的内部更加平易近人。不知怎么的,当我亲自试用应用程序时,它们似乎影响了我的应用程序的渲染性能,所以我不亲自使用它们。但肯定有一些值得关注的地方。

好吧,就在这里。我知道这仍然是相当技术性的,但我希望它有助于更好地理解编译后的Svelte代码所做的事情。

票数 9
EN

Stack Overflow用户

发布于 2019-11-17 16:16:19

这两个库都尽量减少了需要对dom进行多少更改。不同之处在于他们找出了最低限度的变更是什么。

React的方法是在内存中对dom (虚拟dom)进行表示。设置状态时,它将再次运行呈现过程,以创建另一个虚拟dom。它比较前后,找出改变了什么,然后任何变化都被推到真实的位置。

Svelte的方法是,当您设置一个变量时,它会设置一个标志,将该变量标记为已更改。它知道哪些变量是依赖于其他变量的,因此它会逐步遍历任何因变量并重新计算它们,从而建立一个需要更改的列表。然后,这些更改被推入多数点。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58902385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档