500 行的 Svelte 逆向 table 感觉很慢?

Svelte reversing table of 500 rows feels slow?

我创建了 table 的 500 行,在点击时反转它感觉很慢,主观上大概需要 500 毫秒左右。

性能合理吗?感觉在JS中逆向table of 500行应该会更快

Svelte demo and Pure JS demo.

Pure JS 感觉比 Svelte 快多了

Table.svelte

<script>
  import Cell from "./Cell.svelte"
  
  const template = {
    name: "Barrick Gold Corp",
    symbol: "ABX",
    has_options: true,
    ib_symbol: "GOLD NYSE USD",
    ib_osymbol: "GOLD CBOE USD",
    risk: 0,
    quality: 0,
    brand: 0
  }

  let rows = []
  let id = 0
  for (let i = 0; i < 500; i++) {
    let row = [id++]
    for (let key in template) row.push(("" + template[key]) + i)
    rows.push(row)
  }  
</script>

<table>
  <button on:click={() => rows = rows.reverse()}>change order</button>
  {#each rows as row (row[0])}
    <tr>
      {#each row as cell, j (`${row[0]},${j}`)}
        <Cell value={cell} />
      {/each}
    </tr>
  {/each}
</table>
<script>
  import StringView from "./StringView.svelte"
  
  export let value
</script>

<svelte:component this={StringView} value={value}/>
<script>
  export let value
</script>

<td>{value}</td>

P.S.

Svelte demo with additional Row element 性能感觉与原始精简版相同。

And a version 只有一个 table 元素,没有 Row 和 Cell 元素,感觉有点快

我首先认为它与索引无法正常工作有关,但是当添加 'slice' 按钮和淡入淡出效果时它似乎工作正常 -> 第一个项目淡出并在之后它被完全删除,其他元素向上移动。

SEE THIS 稍微修改一下你的版本

  • 'slice' 添加了按钮和对 StringView 的效果
  • 更新前 -> 后控制台跟踪时间中的计时器

尽管如此,由于我已经想知道如何在嵌套的每个循环 (Nested each loops over array in Svelte - how to set unique id / key?) 数组上正确定义 id (Nested each loops over array in Svelte - how to set unique id / key?),所以我制作了一个版本,其中包含对象而不是行数组,并且只有一个组件用于行。 比较更新时间时,它几乎快了一倍(firstLoad/Update --> ≈700ms/250ms --> 330ms/160ms(在 Firefox 中))-> 看这个 REPL

我仍然想知道这是否可以优化,因为即使 id/key 似乎有效,每个 TableRow 组件都会在顺序颠倒或第一个元素被切片时记录更新。我曾经做过一个非常简单的例子,它的行为不同,只有没有 id 的元素才会记录更新 -> 看这个 REPL

(您的这部分代码可以写得更短 ->

<script>
    function reverse(list) { 
        list = [...list]
        list.reverse()
        return list
    }
</script>
<button on:click={() => rows = reverse(rows)}>change order</button>

像这样--->

<script>
    function reverseRows() { 
      rows = rows.reverse()
    }
</script>
<button on:click={reverseRows}>change order</button>

Row-Object-Component-Solution的代码->

<!--[App.svelte]-->
<script>
    import { beforeUpdate, afterUpdate } from 'svelte';
    import TableRow from './TableRow.svelte';
    
    beforeUpdate(() => {
//      console.log('before Update')
        console.time('time to update');
    });
    afterUpdate(() => {
//      console.log('after Update')
        console.timeEnd('time to update')
    });
    
    const template = {
    name: "Barrick Gold Corp",
    symbol: "ABX",
    has_options: true,
    ib_symbol: "GOLD NYSE USD",
    ib_osymbol: "GOLD CBOE USD",
    risk: 0,
    quality: 0,
    brand: 0
  }

    let rowsAsObj = []
    
    for(let i = 0; i< 500; i++){
        let row = {id: i,}
        for( let key in template){
            row[key] = `${template[key]}${i}`           
        }
        rowsAsObj.push(row)
    }   
    function reverse() { 
        rowsAsObj = rowsAsObj.reverse();
    }
    function slice(){
        rowsAsObj = rowsAsObj.slice(1)
    }
</script>

    <button on:click={reverse}>change order</button>
    <button on:click={slice}>slice</button>

<table>
    {#each rowsAsObj as row (row.id)}
        <TableRow {row}/>
    {/each}
</table>

<style>
    table {
        border-collapse: collapse;
        width: 100%;
    }
</style>
<!--[TableRow.svelte]-->
<script>
    import { fade } from 'svelte/transition'
    
    import { afterUpdate } from 'svelte';
        afterUpdate(() => {
//      console.log('TableRow updated')
    });
    
    export let row;
</script>

<tr transition:fade="{{duration: 800, delay: 800}}">
    {#each Object.values(row) as cell}
        <td>
            {cell}
        </td>
    {/each}
</tr>

<style>
    
    td {
        padding: 5px;
        border-bottom: 1px solid grey;
    }
    
</style>