diff --git a/src/components/table/body/index.js b/src/components/table/body/index.js index 9e36f279..a59485e5 100644 --- a/src/components/table/body/index.js +++ b/src/components/table/body/index.js @@ -1,4 +1,4 @@ -import React, { memo, useCallback, useRef, useEffect } from "react" +import React, { memo, useCallback, useRef, useEffect, useState } from "react" import { useVirtualizer, defaultRangeExtractor } from "@tanstack/react-virtual" import identity from "lodash/identity" import Flex from "@/components/templates/flex" @@ -35,11 +35,38 @@ const Body = memo( initialOffset = 0, onScroll, enableColumnReordering, + deferMeasureMs, ...rest }) => { useTableState(rerenderSelector) const ref = useRef() + const isDeferEnabled = !!deferMeasureMs && deferMeasureMs > 0 + + const scrollTimeoutRef = useRef(null) + const [measureEnabled, setMeasureEnabled] = useState(true) + + const handleScrollDetection = useCallback(() => { + setMeasureEnabled(false) + + if (scrollTimeoutRef.current) { + clearTimeout(scrollTimeoutRef.current) + } + + scrollTimeoutRef.current = setTimeout(() => { + setMeasureEnabled(true) + }, deferMeasureMs) + }, [deferMeasureMs]) + + // Cleanup timeout on unmount + useEffect(() => { + return () => { + if (scrollTimeoutRef.current) { + clearTimeout(scrollTimeoutRef.current) + } + } + }, []) + const { rows } = table.getRowModel() const rowVirtualizer = useVirtualizer({ @@ -64,6 +91,22 @@ const Body = memo( }, []), }) + const measureRef = useCallback( + node => { + if (!isDeferEnabled || (measureEnabled && node)) { + rowVirtualizer.measureElement(node) + return + } + }, + [isDeferEnabled, measureEnabled, rowVirtualizer] + ) + + useEffect(() => { + if (isDeferEnabled && measureEnabled) { + rowVirtualizer.measure() + } + }, [isDeferEnabled, measureEnabled, rowVirtualizer]) + if (virtualRef) virtualRef.current = rowVirtualizer const virtualRows = rowVirtualizer.getVirtualItems() @@ -99,7 +142,10 @@ const Body = memo( overflow="auto" flex="1" data-testid={`netdata-table${testPrefix}`} - onScroll={onScroll} + onScroll={e => { + if (isDeferEnabled) handleScrollDetection() + if (onScroll) onScroll(e) + }} >