Búsqueda de sitios web

typescript - Rendimiento lento al desplazarse con 9 columnas usando react-virtualized


Estoy usando react-virtualized junto con celdas de tabla de material-ui para crear una tabla con desplazamiento virtual, todo parece estar bien, pero ocasionalmente noto una desaceleración en el rendimiento al recorrer la tabla en ambas direcciones, hacia arriba y hacia abajo. Abrí la consola de desarrollo y encontré algunas advertencias allí, numerosas.

[Violación] el manejador de 'requestAnimationFrame' tardó ~116ms

Y

[Violación] el controlador 'scroll' tomó ~150ms

mensajes.

  const MyTable: React.FunctionComponent<Props> = (props: Props) => {
  
    //props, styles, table content fetching here
  
    const headerRenderer = () => {
        return (
            <MyHeaderCell
                styleClass={classes.headerCell}
                content={"Header"}
            />
        );
    };

    const cellRenderer = (rendererProps) => {
        return (
            <MyContentCell
                styleClass={classes.tableCell}
                rendererProps={rendererProps}
            />
        );
    };

    const renderContent = () => {
        return (
            <InfiniteLoader
                isRowLoaded={isRowLoaded}
                loadMoreRows={loadMoretableItems}
                rowCount={tableItemsQuantity}
            >
                {({ onRowsRendered}) => (
                    <AutoSizer>
                        {(sizerProps: IAutoSizerProps) => {
                            const { height, width } = sizerProps;
                            return (
                                <Table
                                    onRowsRendered={onRowsRendered}
                                    width={width}
                                    height={height}
                                    rowHeight={rowHeight}
                                    rowCount={tableItems.length}
                                    rowGetter={getCurrentRow}
                                    overscanRowCount={5}
                                    headerHeight={rowHeight}
                                    rowClassName={classes.flexContainer}
                                    noRowsRenderer={noRowsRenderer}
                                >
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.id)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop1)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop2)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop3)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop4)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop5)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop6)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop7)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                    <Column
                                        dataKey={nameof<MyTableItem>((o) => o.prop8)}
                                        width={width}
                                        headerClassName={clsx(classes.header, classes.column)}
                                        headerRenderer={headerRenderer}
                                        className={clsx(classes.header, classes.column)}
                                        cellRenderer={cellRenderer}
                                    />
                                </Table>
                            );
                        }}
                    </AutoSizer>
                )}
            </InfiniteLoader>
        );
    };

    return (
        <Grid item container direction={"column"} className={classes.root}>
            <h4>{Translate.getString("My Table Items")}</h4>
            <Grid item className={classes.tableContainer}>
                {renderContent}
                <LoaderBlock isLoading={showTableLoader}/>
            </Grid>
        </Grid>
    );
};

export { MyTable };

¿Qué puedo hacer para mejorar el rendimiento de mi tabla?

Respuesta #1

Bueno, por si alguien se pregunta cómo solucionar esto, reducir la anidación de HTML en celdas y encabezados me ayudó mucho a reducir el retraso al recorrer la tabla. Los componentes de Material UI producen un árbol de elementos bastante grande -> a react-virtualized le cuesta renderizar componentes pesados mientras va mostrando los elementos, así que deberías mantenerlo lo más simple posible.