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[]>([]); @@ -121,6 +121,7 @@ const miniTableData = ref<any[]>([]);
const estimatedRowHeight = ref<number | undefined>(undefined);
const estimatedHeaderHeight = ref<number | undefined>(undefined);
let miniTableResizeObserver: ResizeObserver | null = null;
let lastMiniTableHeight = 0;
// Header height constant
@ -170,6 +171,7 @@ interface Props { @@ -170,6 +171,7 @@ interface Props {
columns?: ListTableColumn<T>[];
page?: boolean;
height?: number | string;
minHeight?: number | string;
maxHeight?: number | string;
example?: any;
rowKey?: string;
@ -189,6 +191,7 @@ const prop = withDefaults(defineProps<Props>(), { @@ -189,6 +191,7 @@ const prop = withDefaults(defineProps<Props>(), {
columns: () => [],
page: false,
height: undefined,
minHeight: 300,
maxHeight: undefined,
example: () => ({}),
rowKey: "id",
@ -261,6 +264,8 @@ watch( @@ -261,6 +264,8 @@ watch(
if (rowHeight && rowHeight > 0) {
estimatedRowHeight.value = rowHeight;
}
// Update last known mini-table height for ResizeObserver comparison
lastMiniTableHeight = miniTableRef.value?.offsetHeight || 0;
},
{ immediate: true }
);
@ -276,13 +281,23 @@ function estimateTableRowHeight() { @@ -276,13 +281,23 @@ function estimateTableRowHeight() {
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(() => {
// 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 () => {
if (!shouldUseProbeRow.value || miniTableData.value.length === 0) {
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 new Promise((resolve) => requestAnimationFrame(resolve));
await new Promise((resolve) => requestAnimationFrame(resolve));
@ -300,16 +315,17 @@ onMounted(() => { @@ -300,16 +315,17 @@ onMounted(() => {
estimatedRowHeight.value = newRow;
estimatedHeaderHeight.value = newHeader;
});
}, 50);
}, 200);
// Use ResizeObserver on .my-table to detect width changes
// This is better than window resize because it only fires when OUR container changes
// Observe miniTableRef for height 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(() => {
handleResize();
});
if (myTableRef.value) {
miniTableResizeObserver.observe(myTableRef.value);
if (miniTableRef.value) {
miniTableResizeObserver.observe(miniTableRef.value);
}
});
@ -480,7 +496,7 @@ const tableColumns = computed(() => { @@ -480,7 +496,7 @@ const tableColumns = computed(() => {
col.cellRenderer = renderCellContent;
// Header cell renderer - use custom headerCellRenderer if provided
col.headerCellRenderer = undefined; // TODO
col.headerCellRenderer = renderHeaderCellContent;
col._listTableColumn = column;
return col;

Loading…
Cancel
Save