Browse Source

WIP: optimize resize performance

dev
hechang27-sprt 3 months ago
parent
commit
8fc90c168e
  1. 32
      packages/base/data/list-table-v2.vue

32
packages/base/data/list-table-v2.vue

@ -121,6 +121,7 @@ const miniTableData = ref<any[]>([]);
const estimatedRowHeight = ref<number | undefined>(undefined); const estimatedRowHeight = ref<number | undefined>(undefined);
const estimatedHeaderHeight = ref<number | undefined>(undefined); const estimatedHeaderHeight = ref<number | undefined>(undefined);
let miniTableResizeObserver: ResizeObserver | null = null; let miniTableResizeObserver: ResizeObserver | null = null;
let lastMiniTableHeight = 0;
// Header height constant // Header height constant
@ -170,6 +171,7 @@ interface Props {
columns?: ListTableColumn<T>[]; columns?: ListTableColumn<T>[];
page?: boolean; page?: boolean;
height?: number | string; height?: number | string;
minHeight?: number | string;
maxHeight?: number | string; maxHeight?: number | string;
example?: any; example?: any;
rowKey?: string; rowKey?: string;
@ -189,6 +191,7 @@ const prop = withDefaults(defineProps<Props>(), {
columns: () => [], columns: () => [],
page: false, page: false,
height: undefined, height: undefined,
minHeight: 300,
maxHeight: undefined, maxHeight: undefined,
example: () => ({}), example: () => ({}),
rowKey: "id", rowKey: "id",
@ -261,6 +264,8 @@ watch(
if (rowHeight && rowHeight > 0) { if (rowHeight && rowHeight > 0) {
estimatedRowHeight.value = rowHeight; estimatedRowHeight.value = rowHeight;
} }
// Update last known mini-table height for ResizeObserver comparison
lastMiniTableHeight = miniTableRef.value?.offsetHeight || 0;
}, },
{ immediate: true } { immediate: true }
); );
@ -276,13 +281,23 @@ function estimateTableRowHeight() {
return { headerHeight, rowHeight }; return { headerHeight, rowHeight };
} }
// Setup ResizeObserver on mount (not window resize - that causes flickering) // Setup ResizeObserver on mount
// Observe miniTableRef instead of myTableRef - only re-probe if mini-table's rendered height changes
// This avoids unnecessary re-probing during window resize when container width changes but row heights stay same
onMounted(() => { onMounted(() => {
// Resize handler - measure first, then clear and set in same microtask // Resize handler - only re-probe if the mini-table's actual height changed
const handleResize = lodash.debounce(async () => { const handleResize = lodash.debounce(async () => {
if (!shouldUseProbeRow.value || miniTableData.value.length === 0) { if (!shouldUseProbeRow.value || miniTableData.value.length === 0) {
return; return;
} }
// Check if mini-table height actually changed (e.g., due to text wrapping)
const currentHeight = miniTableRef.value?.offsetHeight || 0;
if (currentHeight === lastMiniTableHeight) {
return; // Height unchanged, no need to re-probe
}
lastMiniTableHeight = currentHeight;
await nextTick(); await nextTick();
await new Promise((resolve) => requestAnimationFrame(resolve)); await new Promise((resolve) => requestAnimationFrame(resolve));
await new Promise((resolve) => requestAnimationFrame(resolve)); await new Promise((resolve) => requestAnimationFrame(resolve));
@ -300,16 +315,17 @@ onMounted(() => {
estimatedRowHeight.value = newRow; estimatedRowHeight.value = newRow;
estimatedHeaderHeight.value = newHeader; estimatedHeaderHeight.value = newHeader;
}); });
}, 50); }, 200);
// Use ResizeObserver on .my-table to detect width changes // Observe miniTableRef for height changes
// This is better than window resize because it only fires when OUR container changes // The mini-table's height only changes when column widths cause text to wrap
// During typical window resize with fixed-height content, height stays same no re-probe
miniTableResizeObserver = new ResizeObserver(() => { miniTableResizeObserver = new ResizeObserver(() => {
handleResize(); handleResize();
}); });
if (myTableRef.value) { if (miniTableRef.value) {
miniTableResizeObserver.observe(myTableRef.value); miniTableResizeObserver.observe(miniTableRef.value);
} }
}); });
@ -480,7 +496,7 @@ const tableColumns = computed(() => {
col.cellRenderer = renderCellContent; col.cellRenderer = renderCellContent;
// Header cell renderer - use custom headerCellRenderer if provided // Header cell renderer - use custom headerCellRenderer if provided
col.headerCellRenderer = undefined; // TODO col.headerCellRenderer = renderHeaderCellContent;
col._listTableColumn = column; col._listTableColumn = column;
return col; return col;

Loading…
Cancel
Save