-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
Description
TanStack Table version
v9.0.0-alpha.10
Framework/Library version
Svelte 5.0.0-next.244
Describe the bug and the steps to reproduce it
Hello, I've been using Tanstack Table v9 with svelte 5 + sveltekit and getting weird performance issue.
This is the function to insert a new row at starting of the table. I'm updating table data and inserting a new row with websocket message that is coming every one second from server. Basically I'm inserting a new row every 1 second and it gives weird console warnings and after 50-60 seconds application starts lagging and eventually crashes. I've attached console log warnings below.
I've noticed some other important points related to this:
- If I insert a new row every 5 second instead of every 1 second, issue still persist
- If I have applied filters on the data such that no data will be in list then it do not lag.(e.g. if age is ranged 0 to 30 and filter it to min 31)
- As many rows I insert lag and pause time increases. Almost same time as the console warning
- Debouncing the
rowModel = table.getRowModel();isn't working at all
- Tanstack Table Version: ^9.0.0-alpha.10
- Svelte: ^5.0.0-next.244
- Sveltekit: ^2.0.0
- @sveltejs/vite-plugin-svelte: ^4.0.0-next.6
I assume that this is rendering related issue.. I've also attached snippet for how i'm rendering the table.
export const insertNewRow = (rowData) => {
if (isAnimatingRow) return;
animateInsertRow = true;
isAnimatingRow = true;
document.getElementById('main-layout').scrollTo({ top: 0, behavior: 'smooth' });
data = [rowData, ...data.slice(0, 49)];
setTimeout(() => {
animateInsertRow = false;
isAnimatingRow = false;
}, 500);
};
//other code
$effect(() => {
if (sorting || filters || data) {
rowModel = table.getRowModel();
}
});
<div class="table select-none flex text-xs md:text-sm w-full">
<div class="table-root sticky top-0 flex flex-col">
<div
class={`relative table-header grid border-b-2 border-border sticky top-[52px] z-10 lg:rounded-t-md`}
style:grid-template-columns={`${tableGridLayout}`}
bind:this={gridHeaderLayout}
>
{#each table.getHeaderGroups() as headerGroup, ind (ind)}
{#each headerGroup.headers as header, index (index)}
<div
class="table-header-cell border-b border-borderLight bg-card px-4 h-10 flex items-center grow-1"
class:sticky={header.column.columnDef.pinned}
class:left-0={header.column.columnDef.pinned}
class:z-10={header.column.columnDef.pinned}
style:top={`${headerTopOffset}px`}
style:left={`${header.column.columnDef.leftOffset || 0}px`}
class:justify-end={index !== 0}
class:border-r={index !== headerGroup.headers.length - 1}
>
{#if !header.isPlaceholder}
{#if header.column.getCanSort()}
<button
class="flex gap-2"
onclick={() => {
console.log(sorting[0]);
if (sorting[0] && sorting[0].id === header.column.columnDef.accessorKey) {
updateExternalSort(
header.column.columnDef.accessorKey,
sorting[0] ? (sorting[0].desc ? 'asc' : 'none') : 'desc'
);
} else {
updateExternalSort(header.column.columnDef.accessorKey, 'desc');
}
}}
>
{#if typeof header.column.columnDef.header === 'function'}
{header.column.columnDef.header()}
{:else}
{header.column.columnDef.header}
{/if}
{#if header.column.getIsSorted().toString() === 'asc'}
<PrimeSortUpFill />
{:else if header.column.getIsSorted().toString() === 'desc'}
<PrimeSortDownFill />
{/if}
</button>
{:else if typeof header.column.columnDef.header === 'function'}
{header.column.columnDef.header()}
{:else}
{header.column.columnDef.header}
{/if}
{/if}
</div>
{/each}
{/each}
</div>
<div
class={`relative flex-grow table-body ${rowModel.rows.length === 0 && 'h-[calc(100vh-359px)] sm:h-[calc(100vh-301px)] md:h-[calc(100vh-319px)]'}`}
bind:this={tableBody}
>
{#if isLoading}
<TableLoader gridLayout={tableGridLayout} columns={columnDef.length} />
{:else if rowModel.rows.length === 0}
<div class={`size-full min-h-full max-w-[100vw] lg:max-w-[calc(100vw-256px)] bg-card p-4`}>
<div
class="text-center p-4 border border-dashed min-h-full rounded-button text-xl flex items-center justify-center"
>
<span class="text-highlight">{notFound}</span>
</div>
</div>
{:else}
{#each rowModel.rows as row, rowIndex (row.original.id)}
<div
class={`table-row grid group`}
style:grid-template-columns={tableGridLayout}
animate:flip={{ duration: 300 }}
in:fly={getTransition(rowIndex)}
out:slide={{ duration: 300 }}
>
<!-- Maybe only this:
in:fly="{{ y: rowIndex === 0 && animateInsertRow ? 50 : 0, duration: 300 }}" -->
{#each row.getVisibleCells() as cell, cellIndex (cellIndex)}
<div
class="table-cell p-3 flex items-center border-b border-borderLight grow-1 group-hover:bg-modal"
class:pinned={cell.column.columnDef.pinned}
class:bg-background={cell.column.columnDef.pinned}
class:border-b-0={rowIndex === rowModel.rows.length - 1}
class:lg:rounded-bl-md={rowIndex === rowModel.rows.length - 1 && cellIndex === 0}
class:lg:rounded-br-md={rowIndex === rowModel.rows.length - 1 &&
cellIndex === row.getVisibleCells().length - 1}
class:border-r={cellIndex !== row.getVisibleCells().length - 1}
style:left={`${cell.column.columnDef.leftOffset || 0}px`}
class:justify-end={cellIndex !== 0}
>
{#if cell.column.columnDef.component}
{@const { component: CustomComponent, props } = cell.column.columnDef.cell(
cell.getContext()
)}
<CustomComponent {...props} />
{:else}
{cell.getValue()}
{/if}
</div>
{/each}
</div>
{/each}
{/if}
</div>
</div>
</div>
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
'
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
