Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poor performance on Table (Unusable atm) #4758

Open
J4v4Scr1pt opened this issue Jan 29, 2025 · 6 comments
Open

Poor performance on Table (Unusable atm) #4758

J4v4Scr1pt opened this issue Jan 29, 2025 · 6 comments

Comments

@J4v4Scr1pt
Copy link

J4v4Scr1pt commented Jan 29, 2025

I'm implementing a table but are experience a lot of sluggish behavior, especially if there are many rows.
Tested with react-scan and wonder if this is normal to have whole component re-render when you open the menu or just by clicking on the row with "selectionMode" set to none.
Using the "Use Case" example from the docs.

Recording.2025-01-02.163328.mp4

As a PRO user I have also tried that table but even with all the useMemoizedCallback and other memoization methods its still very sluggish to use.

Originally posted by @J4v4Scr1pt in #4480

Copy link

linear bot commented Jan 29, 2025

@AnYiEE
Copy link
Contributor

AnYiEE commented Jan 29, 2025

#4590 ?

@J4v4Scr1pt
Copy link
Author

J4v4Scr1pt commented Jan 29, 2025

#4590 ?

Good suggestion, could be related :) . But the hovering is no issue, It's probably hard to see in the video, but it's all interaction with the table.
e.g. opening the actions menu(three dot menu) takes up to 1-1.5sec before its opening or by just clicking on the row.

Here is an example with the Pro table:
https://github.com/user-attachments/assets/b836480f-d987-4784-a38b-1548430263d1

@J4v4Scr1pt
Copy link
Author

J4v4Scr1pt commented Jan 29, 2025

In my case I have around 20-30 rows and I have so much performance issues with it that I'm actually thinking of just using an styled native table instead.

I have a hard time understanding the issues, trying my best to debug. Any suggestions are much appreciated.

I have tried to remove all surrounding application code like navigation and such to only have HeroUI provider and the table, but it still performs sluggish.

Edit:
To give some more context, I have now a NextJS application using latest versions of nextjs, react and heroui. In the main layout I only render the Pro example Table nothing else, not even the Provider, using only the provided example data and the table still has issues as I shown in above videos.

@J4v4Scr1pt J4v4Scr1pt changed the title Poor performance on Table Poor performance on Table (Unusable atm) Jan 30, 2025
@Drew-Chase
Copy link

I'm having the same issue, I've been unable to memoize the rows. I get a Unknown element <[object Object]> in collection. error

Here is the full error
Uncaught Error: Unknown element <[object Object]> in collection.
    getFullNode http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:34982
    childNodes http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:35043
    Symbol.iterator http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:35063
    visit http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:49421
    $788781baa30117fa$export$596e1b2e2cf93690 http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:49423
    collection http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:49471
    result http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:35090
    updateMemo http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:5153
    useMemo http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:16649
    react React
    $7613b1592d41b092$export$6cd28814d92fa9c9 http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:35084
    $4a0dd036d492cee4$export$907bcc6c48325fd6 http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:49471
    useTable http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:49725
    Table http://127.0.0.1:1421/node_modules/.vite/deps/@heroui_react.js?v=9b4562f9:50310
    frame http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:16192
    renderWithHooks http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:4306
    updateForwardRef http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:5813
    beginWork http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:7244
    runWithFiberInDEV http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:726
    performUnitOfWork http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:10831
    workLoopSync http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:10692
    renderRootSync http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:10675
    performWorkOnRoot http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:10323
    performSyncWorkOnRoot http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:11448
    flushSyncWorkAcrossRoots_impl http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:11356
    flushSyncWork$1 http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:10533
    scheduleRefresh http://127.0.0.1:1421/node_modules/.vite/deps/react-dom_client.js?v=9b4562f9:381
    scheduleRefresh <anonymous code>:1
    performReactRefresh http://127.0.0.1:1421/@react-refresh:188
    performReactRefresh http://127.0.0.1:1421/@react-refresh:180
    enqueueUpdate http://127.0.0.1:1421/@react-refresh:474
    setTimeout handler*debounce/< http://127.0.0.1:1421/@react-refresh:465
    validateRefreshBoundaryAndEnqueueUpdate http://127.0.0.1:1421/@react-refresh:512
    <anonymous> http://127.0.0.1:1421/src/assets/pages/TestTablePage.tsx?t=1738336805680:275
    accept http://127.0.0.1:1421/@vite/client:34
    fetchUpdate http://127.0.0.1:1421/@vite/client:208
    queueUpdate http://127.0.0.1:1421/@vite/client:183
    queueUpdate http://127.0.0.1:1421/@vite/client:183
    handleMessage http://127.0.0.1:1421/@vite/client:879
    handleMessage http://127.0.0.1:1421/@vite/client:877
    onMessage http://127.0.0.1:1421/@vite/client:298
    connect http://127.0.0.1:1421/@vite/client:428
@heroui_react.js:34982:15

Code
import {Button, cn, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Select, SelectItem, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow} from "@heroui/react";
import {Icon} from "@iconify/react";
import {memo, useMemo} from "react";
import {Departments} from "../ts/printer.ts";
import $ from "jquery";

export default function TestTablePage()
{
    return (
        <Table
            removeWrapper
            isStriped
            isHeaderSticky
            className={"w-auto mx-8 mt-4 grow"}
            classNames={{
                td: cn(
                    "data-[price]:!text-danger data-[mp]:!text-success data-[price]:!font-bold data-[mp]:!font-bold",
                    "before:!bg-transparent"
                ),
                tr: cn(
                    "data-[selected=true]:!bg-primary/20 data-[selected=true]:data-[hover=true]:!bg-primary/30",
                    "data-[odd=true]:bg-foreground/5 data-[hover=true]:hover:bg-foreground/10 transition-colors",
                    "dark:data-[odd=true]:bg-default-100/10 dark:data-[hover=true]:hover:bg-default-100/50"
                ),
                th: "dark:bg-background/50 backdrop-blur-md saturation-150 dark:brightness-150 mx-2",
                base: "max-h-[calc(100dvh_-_150px)] overflow-y-auto min-h-[250px]"
            }}
        >
            <TableHeader>
                <TableColumn>UPC</TableColumn>
                <TableColumn>Description</TableColumn>
                <TableColumn>Retail</TableColumn>
                <TableColumn>Department</TableColumn>
                <TableColumn>Actions</TableColumn>
            </TableHeader>
            <TableBody>
                {Array.from({length: 300}).map((_, index) => (
                    <InventoryTableRow id={index}/>
                ))}
            </TableBody>
        </Table>
    );
}


// This function causes the error
const InventoryTableRow = memo(function InventoryTableRow({id}: { id: number })
{
    return (
        <TableRow>
            <TableCell>194346264193</TableCell>
            <TableCell>*HARV SHAP CKIE 12OZ</TableCell>
            <TableCell>$4.48</TableCell>
            <TableCell><DepartmentDropdown id={id.toString()}/></TableCell>
            <TableCell>
                <DropdownExample key={``} index={id}/>
            </TableCell>
        </TableRow>
    );
});

const DropdownExample = memo(function DropdownExample({index}: { index: number })
{
    return (
        <Dropdown key={`action-dropdown-${index}`}>
            <DropdownTrigger>
                <Button>
                    <Icon icon="mdi:dots-vertical"/>
                </Button>
            </DropdownTrigger>
            <DropdownMenu>
                <DropdownItem key={`action-${index}`}>Action</DropdownItem>
                <DropdownItem key={`another-action-${index}`}>Another action</DropdownItem>
            </DropdownMenu>
        </Dropdown>
    );
});

const DepartmentDropdown = memo(function DepartmentDropdown({id}: { id: string })
{
    const filteredDepartments = useMemo(() =>
            Departments.filter(i => i.id > 0),
        [Departments]
    );

    return (
        <Select
            key={`${id}-dept-selector`}
            label={"Department"}
            placeholder={"Select a department to print"}
            radius={"full"}
            classNames={{}}
            onSelectionChange={selection =>
            {
                const dept = Departments.find(i => i.id === +(
                    ([...selection][0] as string)
                        .replace(`${id}-`, "")
                        .trim()
                ))?.id ?? -1;
                $(`tr#${id}`).attr("data-department", dept);
            }}
        >
            {
                filteredDepartments.map(
                    dept =>
                        <SelectItem
                            key={`${id}-${dept.id}`}
                            value={dept.name}
                            textValue={dept.name}
                        >
                            {dept.id} - {dept.name}
                        </SelectItem>
                )
            }
        </Select>
    );
});

Image

20250131-1600-56.8630991.mp4

@J4v4Scr1pt
Copy link
Author

@Drew-Chase I also got this if I used the table components outside of the table and not directly nested. I can share my implementation on Monday when I'm back at the computer. Because I got an ok performance with a max row count of 7 and a lot of memoization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants