question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Performance is too slow while selecting row or moving to next page with 300 rows

See original GitHub issue

Describe the bug (required) I am rendering 100 rows by default having 52 columns with contains links and free text as cell values. whenever i change page count to 300 rows, it takes around 10-12 seconds to reflect new data everytime. Same way it also takes 5-6 seconds while selecting any row with useRowSelect.

Provide an example via Codesandbox! (required) Since there are lots of columns data and rows, can’t exactly create replica in sandbox, but i am uploading my profiler.json which i downloaded from React-Profiler tab. Maybe it will help

Expected behavior (Recommended) It should not take 10-12 seconds to render 300 rows.

Screenshots Screenshot_1

Desktop (please complete the following information):

  • OS: Ubuntu
  • Browser Chrome
  • Version 84.0.4147.125

profiling-data.14-10-2020.17-12-35.zip

Here is my Code:

import React, { useEffect, useCallback, useState } from 'react'
import { useTable, useRowSelect } from 'react-table'
import { getColumn } from './DiamondListFunctions'

const headerProps = (props, { column }) => getStyles(props, column, 'header')
const cellProps = (props, { cell }) => getStyles(props, cell.column, 'cell')
const getStyles = (props, item, type) => [
  props,
  {
    style: {
      textAlign: item.cellClass ? item.cellClass.replace('text-', '') : 'center',
      width: (item.width || '100') + 'px',
      fontWeight: type === 'cell' && (item.id === 'stoneId' || item.id === 'vStnId') ? '600' : '',
      color:
        type === 'cell' && (item.id === 'shpNm' || item.id === 'lbNm' || item.id === 'rptNo' || item.link)
          ? '#008cba'
          : ''
    }
  }
]
const primaryColumns = getColumn()
const Table = React.forwardRef(function Table(props, ref) {

  const {
    data = []
  } = props;

  const [detail, setDetail] = useState(null)

  const IndeterminateCheckbox = React.forwardRef(
    ({ indeterminate, row = {}, isHeader, ...rest }, ref) => {

      const defaultRef = React.useRef()
      const resolvedRef = ref || defaultRef

      React.useEffect(() => {
        resolvedRef.current.indeterminate = indeterminate
      }, [resolvedRef, indeterminate])

      return (
        <div className='selectActionIconWrapper'>
          <input type='checkbox' {...rest} ref={resolvedRef} />
        </div>
      )
    }
  )

  const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, selectedFlatRows } = useTable(
    {
      columns: primaryColumns,
      data,
    },
    useRowSelect,
    hooks => {
      hooks.visibleColumns.push((columns) => [
        {
          id: 'selection',
          Header: ({ getToggleAllRowsSelectedProps }) => (
            <IndeterminateCheckbox
              isHeader={true}
              {...getToggleAllRowsSelectedProps()}
            />
          ),
          Cell: ({ row }) => (
            <IndeterminateCheckbox
              row={row.original}
              {...row.getToggleRowSelectedProps()}
            />
          ),
        },
        ...columns,
      ])
    }
  )

  useEffect(() => {
    //show header in parent component with selected data summary, sum,avg, etc
  }, [selectedFlatRows])

  const clickHandler = useCallback((row, cell) => {
    //handle cell click
  }, [])

  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th
                {...column.getHeaderProps(headerProps)}
                style={{ width: (column.width || 100) + 'px' }}
              >
                {column.render('Header')}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {
          !!rows.length && rows.map(row => {
            prepareRow(row)
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map(cell => (
                  <MemoizedCell
                    key={cell.column.id + '_cell'}
                    cell={cell}
                    clickHandler={clickHandler}
                    row={row}
                    setDetail={setDetail}
                  />
                )
                )}
              </tr>
            )
          })
        }
      </tbody>
    </table >
  )
})

const MemoizedCell = React.memo(({ cell, clickHandler, row, setDetail }) => {
  return (
    <td
      {...cell.getCellProps(cellProps)}
      onClick={() => clickHandler(row, cell)}
    >
      {cell.column.id !== 'Details' && cell.render('Cell')}
      {cell.column.id === 'Details' && (
        <Resource original={row.original} setDetail={setDetail} />
      )}
    </td>
  )
})

const Resource = React.memo(({ original, setDetail }) => {
  const { img, videoFile, certFile } = original;

  let imageSource = '', detailKey = ''
  if (img) {
    imageSource = require('../../assets/svg/camera.svg')
    detailKey = 'i'
  } else if (videoFile) {
    imageSource = require('../../assets/svg/video.svg')
    detailKey = 'v'
  } else if (certFile) {
    imageSource = require('../../assets/svg/certi.svg')
    detailKey = 'c'
  }

  const clickHandler = useCallback(() => {
    setDetail({
      detail: { [detailKey]: original }
    })
  }, [original, setDetail, detailKey])

  return (
    <img
      style={{ marginRight: '5px' }}
      src={imageSource}
      width='15px'
      alt=''
      onClick={clickHandler}
    />
  )
})

export default React.memo(Table)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:22
  • Comments:8

github_iconTop GitHub Comments

1reaction
e-monsoncommented, Jul 8, 2021

This is a huge issue for me currently, and I’ve been able to find very little information about possible workarounds.

0reactions
tannerlinsleycommented, Apr 5, 2022

This issue is either:

  • Outdated
  • Stale
  • Fixed in v8
  • Unable to be fixed in v7 without breaking changes and is slated for v8

If you feel this is incorrect, please reopen a new issue with a codesandbox reproduction or more info regarding the issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Performance is too slow while selecting row or moving to next ...
whenever i change page count to 300 rows, it takes around 10-12 seconds to reflect new data everytime. Same way it also takes...
Read more >
Simple query performance on 300M row table is very slow ...
I have an ever-growing table that I feel isn't anywhere near as performant as it should be. With around 300M rows and growing...
Read more >
Bug analysis: slowness when working with a large table in IE
We tested with 300 rows and already saw the slowness when selecting a row. The more rows we had, the slower it gets....
Read more >
Large tables are slow to respond with collaborative editing ...
Summary. When editing very large tables in Confluence, any text that is input lags a couple of seconds behind after input.
Read more >
Why my Power BI Matrix or Table Visual is SLOW - RADACAD
In this article, I'm going to explain why the matrix and table in your Power BI ... Note that the total row is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found