Skip to content

Commit

Permalink
chore: spike - improve performance with early return
Browse files Browse the repository at this point in the history
  • Loading branch information
bwittenberg committed Jun 4, 2024
1 parent 3370857 commit 05ed8c1
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
12 changes: 11 additions & 1 deletion packages/react/src/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,23 @@ function DataTable<Data extends UniqueRow>({
initialSortColumn,
initialSortDirection,
}: DataTableProps<Data>) {
const {headers, rows, actions, gridTemplateColumns} = useTable({
const {
headers,
rows,
actions,
gridTemplateColumns,
willReactThrowOutRenderResult: willTriggerRerender,
} = useTable({
data,
columns,
initialSortColumn,
initialSortDirection,
})

if (willTriggerRerender) {
return null
}

return (
<Table
aria-labelledby={labelledby}
Expand Down
63 changes: 62 additions & 1 deletion packages/react/src/DataTable/__tests__/DataTable.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import userEvent from '@testing-library/user-event'
import {render, screen, queryAllByRole} from '@testing-library/react'
import React from 'react'
import React, {Profiler, type ComponentProps} from 'react'
import {DataTable, Table} from '../../DataTable'
import type {Column} from '../column'
import {createColumnHelper} from '../column'
Expand Down Expand Up @@ -857,6 +857,41 @@ describe('DataTable', () => {
expect(customSortFn).toHaveBeenCalled()
expect(getCellContentByColumnHeaderName('Value')).toEqual(['3', '2', '1'])
})

it('should sort again when data changes', async () => {
type Data = {id: string; value: string}
const columns: ComponentProps<typeof DataTable<Data>>['columns'] = [
{
header: 'Value',
field: 'value',
sortBy: true,
},
]
const data: ComponentProps<typeof DataTable<Data>>['data'] = [
{
id: '3',
value: '3',
},
{
id: '2',
value: '2',
},
]
const {rerender} = render(
<DataTable data={data} columns={columns} initialSortColumn="value" initialSortDirection="ASC" />,
)

rerender(
<DataTable
data={data.concat({id: '1', value: '1'})}
columns={columns}
initialSortColumn="value"
initialSortDirection="ASC"
/>,
)

expect(getCellContentByColumnHeaderName('Value')).toEqual(['1', '2', '3'])
})
})

describe('column widths', () => {
Expand Down Expand Up @@ -1036,4 +1071,30 @@ describe('DataTable', () => {
})
})
})

describe('performance tests', () => {
it('should not render twice on initial render', () => {
type Data = {id: string; value: string}
const columns: ComponentProps<typeof DataTable<Data>>['columns'] = [
{
header: 'Value',
field: 'value',
},
]
const data: ComponentProps<typeof DataTable<Data>>['data'] = [
{
id: '1',
value: 'one',
},
]
let renderCount = 0
render(
<Profiler id="DataTable" onRender={() => renderCount++}>
<DataTable data={data} columns={columns} />
</Profiler>,
)

expect(renderCount).toBe(1)
})
})
})
9 changes: 6 additions & 3 deletions packages/react/src/DataTable/useTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function useTable<Data extends UniqueRow>({
data,
initialSortColumn,
initialSortDirection,
}: TableConfig<Data>): Table<Data> {
}: TableConfig<Data>): Table<Data> & {willReactThrowOutRenderResult: boolean} {
const [rowOrder, setRowOrder] = useState(data)
const [prevData, setPrevData] = useState<typeof data | null>(null)
const [prevColumns, setPrevColumns] = useState(columns)
Expand All @@ -58,7 +58,8 @@ export function useTable<Data extends UniqueRow>({

// Reset the `sortByColumn` state if the columns change and that column is no
// longer provided
if (columns !== prevColumns) {
const haveColumnsChanged = columns !== prevColumns
if (haveColumnsChanged) {
setPrevColumns(columns)
if (sortByColumn) {
const column = columns.find(column => {
Expand Down Expand Up @@ -94,7 +95,8 @@ export function useTable<Data extends UniqueRow>({
})

// Update the row order and apply the current sort column to the incoming data
if (data !== prevData) {
const hasDataChanged = data !== prevData
if (hasDataChanged) {
setPrevData(data)
setRowOrder(data)
if (sortByColumn) {
Expand Down Expand Up @@ -207,6 +209,7 @@ export function useTable<Data extends UniqueRow>({
sortBy,
},
gridTemplateColumns,
willReactThrowOutRenderResult: hasDataChanged || haveColumnsChanged,
}
}

Expand Down

0 comments on commit 05ed8c1

Please sign in to comment.