From 54115c5187196273184d5e60dea5f54b6897af5c Mon Sep 17 00:00:00 2001 From: Lauri Date: Fri, 22 Nov 2024 00:00:10 +0100 Subject: [PATCH 1/7] Improved performance for grid resizing --- .../virtualization/useGridVirtualScroller.tsx | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 86435660917e..47d81e40a950 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -6,7 +6,6 @@ import { } from '@mui/utils'; import useLazyRef from '@mui/utils/useLazyRef'; import useTimeout from '@mui/utils/useTimeout'; -import { useResizeObserver } from '@mui/x-internals/useResizeObserver'; import { useRtl } from '@mui/system/RtlProvider'; import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext'; @@ -52,7 +51,7 @@ const MINIMUM_COLUMN_WIDTH = 50; interface PrivateApiWithInfiniteLoader extends GridPrivateApiCommunity, - GridInfiniteLoaderPrivateApi {} + GridInfiniteLoaderPrivateApi { } export type VirtualScroller = ReturnType; @@ -135,7 +134,41 @@ export const useGridVirtualScroller = () => { const columnsTotalWidth = dimensions.columnsTotalWidth; const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector); - useResizeObserver(mainRef, () => apiRef.current.resize()); + const mainRefCallback = React.useCallback((node: HTMLDivElement | null) => { + mainRef.current = node; + + if (node) { + const initialRect = node.getBoundingClientRect(); + let lastSize = { + width: initialRect.width, + height: initialRect.height + }; + + apiRef.current.publishEvent('resize', lastSize); + + const observer = new ResizeObserver((entries) => { + const entry = entries[0]; + if (!entry) return; + + const newSize = { + width: entry.contentRect.width, + height: entry.contentRect.height + }; + + if (newSize.width === lastSize.width && newSize.height === lastSize.height) return; + + apiRef.current.publishEvent('resize', newSize); + + lastSize = newSize; + }); + + observer.observe(mainRef.current); + + return () => { + observer.disconnect(); + } + } + }, []); /* * Scroll context logic @@ -549,11 +582,6 @@ export const useGridVirtualScroller = () => { apiRef.current.publishEvent('virtualScrollerContentSizeChange'); }, [apiRef, contentSize]); - useEnhancedEffect(() => { - // FIXME: Is this really necessary? - apiRef.current.resize(); - }, [apiRef, rowsMeta.currentPageTotalHeight]); - useEnhancedEffect(() => { // TODO a scroll reset should not be necessary if (enabledForColumns) { @@ -596,7 +624,7 @@ export const useGridVirtualScroller = () => { setPanels, getRows, getContainerProps: () => ({ - ref: mainRef, + ref: mainRefCallback, }), getScrollerProps: () => ({ ref: scrollerRef, From 4739f0524ec7be8a85c60272ecfc0551d59eb38d Mon Sep 17 00:00:00 2001 From: lauri865 Date: Fri, 22 Nov 2024 14:31:39 +0100 Subject: [PATCH 2/7] please the ci --- .../virtualization/useGridVirtualScroller.tsx | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 47d81e40a950..8d0b57f51372 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -51,7 +51,7 @@ const MINIMUM_COLUMN_WIDTH = 50; interface PrivateApiWithInfiniteLoader extends GridPrivateApiCommunity, - GridInfiniteLoaderPrivateApi { } + GridInfiniteLoaderPrivateApi {} export type VirtualScroller = ReturnType; @@ -134,41 +134,50 @@ export const useGridVirtualScroller = () => { const columnsTotalWidth = dimensions.columnsTotalWidth; const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector); - const mainRefCallback = React.useCallback((node: HTMLDivElement | null) => { - mainRef.current = node; + const mainRefCallback = React.useCallback( + (node: HTMLDivElement | null) => { + // @ts-ignore + mainRef.current = node; + + if (!node) { + return undefined; + } - if (node) { const initialRect = node.getBoundingClientRect(); let lastSize = { width: initialRect.width, - height: initialRect.height + height: initialRect.height, }; apiRef.current.publishEvent('resize', lastSize); const observer = new ResizeObserver((entries) => { const entry = entries[0]; - if (!entry) return; + if (!entry) { + return; + } const newSize = { width: entry.contentRect.width, - height: entry.contentRect.height + height: entry.contentRect.height, }; - if (newSize.width === lastSize.width && newSize.height === lastSize.height) return; + if (newSize.width === lastSize.width && newSize.height === lastSize.height) { + return; + } apiRef.current.publishEvent('resize', newSize); - lastSize = newSize; }); - observer.observe(mainRef.current); + observer.observe(node); return () => { observer.disconnect(); - } - } - }, []); + }; + }, + [apiRef, mainRef], + ); /* * Scroll context logic From 22c0e6b0bef35475ffa9d15a8dbb5c66a9372764 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 22 Nov 2024 21:10:29 +0100 Subject: [PATCH 3/7] update mainElementRef type --- packages/x-data-grid/src/hooks/core/useGridRefs.ts | 2 +- .../hooks/features/virtualization/useGridVirtualScroller.tsx | 1 - packages/x-data-grid/src/models/api/gridCoreApi.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/x-data-grid/src/hooks/core/useGridRefs.ts b/packages/x-data-grid/src/hooks/core/useGridRefs.ts index 815c7f56e328..98e266fda316 100644 --- a/packages/x-data-grid/src/hooks/core/useGridRefs.ts +++ b/packages/x-data-grid/src/hooks/core/useGridRefs.ts @@ -5,7 +5,7 @@ export const useGridRefs = ( apiRef: React.MutableRefObject, ) => { const rootElementRef = React.useRef(null); - const mainElementRef = React.useRef(null); + const mainElementRef = React.useRef(null); const virtualScrollerRef = React.useRef(null); const virtualScrollbarVerticalRef = React.useRef(null); const virtualScrollbarHorizontalRef = React.useRef(null); diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 8d0b57f51372..f999d1ccef5a 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -136,7 +136,6 @@ export const useGridVirtualScroller = () => { const mainRefCallback = React.useCallback( (node: HTMLDivElement | null) => { - // @ts-ignore mainRef.current = node; if (!node) { diff --git a/packages/x-data-grid/src/models/api/gridCoreApi.ts b/packages/x-data-grid/src/models/api/gridCoreApi.ts index 1dfaf2834b59..c5d7be49b1fd 100644 --- a/packages/x-data-grid/src/models/api/gridCoreApi.ts +++ b/packages/x-data-grid/src/models/api/gridCoreApi.ts @@ -67,7 +67,7 @@ export interface GridCorePrivateApi< /** * The React ref of the grid main container div element. */ - mainElementRef: React.RefObject; + mainElementRef: React.MutableRefObject; /** * The React ref of the grid's virtual scroller container element. */ From 547a3b5553e2fd0bd39737bd72b6560ef81670b2 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 22 Nov 2024 21:28:27 +0100 Subject: [PATCH 4/7] fix ref warning in react < 19 --- .../virtualization/useGridVirtualScroller.tsx | 11 ++++++++--- packages/x-internals/src/constants.ts | 3 +++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 packages/x-internals/src/constants.ts diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index f999d1ccef5a..d30e75e8fb96 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -7,6 +7,7 @@ import { import useLazyRef from '@mui/utils/useLazyRef'; import useTimeout from '@mui/utils/useTimeout'; import { useRtl } from '@mui/system/RtlProvider'; +import { reactMajor } from '@mui/internal-test-utils'; import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext'; import { useGridRootProps } from '../../utils/useGridRootProps'; @@ -171,9 +172,13 @@ export const useGridVirtualScroller = () => { observer.observe(node); - return () => { - observer.disconnect(); - }; + if (reactMajor >= 19) { + return () => { + mainRef.current = null; + observer.disconnect(); + }; + } + return undefined; }, [apiRef, mainRef], ); diff --git a/packages/x-internals/src/constants.ts b/packages/x-internals/src/constants.ts new file mode 100644 index 000000000000..2028b806152d --- /dev/null +++ b/packages/x-internals/src/constants.ts @@ -0,0 +1,3 @@ +import * as React from 'react'; + +export default parseInt(React.version, 10); From cb4c757ac925f62aa2bd995e537bce4b800156c8 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 22 Nov 2024 21:42:39 +0100 Subject: [PATCH 5/7] fix import --- .../hooks/features/virtualization/useGridVirtualScroller.tsx | 2 +- packages/x-internals/src/{constants.ts => reactMajor.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/x-internals/src/{constants.ts => reactMajor.ts} (100%) diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index d30e75e8fb96..d8e98c0999fd 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -7,7 +7,7 @@ import { import useLazyRef from '@mui/utils/useLazyRef'; import useTimeout from '@mui/utils/useTimeout'; import { useRtl } from '@mui/system/RtlProvider'; -import { reactMajor } from '@mui/internal-test-utils'; +import reactMajor from '@mui/x-internals/reactMajor'; import type { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity'; import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext'; import { useGridRootProps } from '../../utils/useGridRootProps'; diff --git a/packages/x-internals/src/constants.ts b/packages/x-internals/src/reactMajor.ts similarity index 100% rename from packages/x-internals/src/constants.ts rename to packages/x-internals/src/reactMajor.ts From 4ce4e280141bd67445a78449e1bf14048fdf948b Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 22 Nov 2024 22:02:43 +0100 Subject: [PATCH 6/7] fix tests in jsdom --- .../hooks/features/virtualization/useGridVirtualScroller.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index d8e98c0999fd..71e9ac2eb0b4 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -139,7 +139,7 @@ export const useGridVirtualScroller = () => { (node: HTMLDivElement | null) => { mainRef.current = node; - if (!node) { + if (!node || typeof ResizeObserver === 'undefined') { return undefined; } From 0a0d10bdc37d0a610300f6755eb76034c67202c7 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Sat, 23 Nov 2024 13:48:41 +0100 Subject: [PATCH 7/7] fix failing unit tests --- .../features/virtualization/useGridVirtualScroller.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx index 71e9ac2eb0b4..bc635380def6 100644 --- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx +++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx @@ -139,7 +139,7 @@ export const useGridVirtualScroller = () => { (node: HTMLDivElement | null) => { mainRef.current = node; - if (!node || typeof ResizeObserver === 'undefined') { + if (!node) { return undefined; } @@ -151,6 +151,10 @@ export const useGridVirtualScroller = () => { apiRef.current.publishEvent('resize', lastSize); + if (typeof ResizeObserver === 'undefined') { + return undefined; + } + const observer = new ResizeObserver((entries) => { const entry = entries[0]; if (!entry) {