diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index f2314d390..4f9dc3991 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -221,6 +221,10 @@ const props = defineProps<{ }) => Promise; }>(); +const dataGridTraceId = uuid().slice(0, 8); +const dataGridCreatedAt = performance.now(); +const dataGridElapsed = () => `${Math.round(performance.now() - dataGridCreatedAt)}ms`; + const emit = defineEmits<{ reload: [sql?: string, searchText?: string, whereInput?: string, orderBy?: string, limit?: number, offset?: number]; paginate: [offset: number, limit: number, whereInput?: string, orderBy?: string]; @@ -228,6 +232,48 @@ const emit = defineEmits<{ "update:whereInput": [value: string]; }>(); +console.info("[DBX][DataGrid:setup]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + rowCount: props.result.rows.length, + columnCount: props.result.columns.length, + backendMs: props.result.execution_time_ms, + loading: props.loading, +}); + +watch( + () => props.result, + (result) => { + const startedAt = performance.now(); + console.info("[DBX][DataGrid:result:prop]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + rowCount: result.rows.length, + columnCount: result.columns.length, + backendMs: result.execution_time_ms, + loading: props.loading, + elapsedSinceSetup: dataGridElapsed(), + }); + nextTick(() => { + console.info("[DBX][DataGrid:result:nextTick]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + elapsed: `${Math.round(performance.now() - startedAt)}ms`, + loading: props.loading, + }); + requestAnimationFrame(() => { + console.info("[DBX][DataGrid:result:first-frame]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + elapsed: `${Math.round(performance.now() - startedAt)}ms`, + loading: props.loading, + }); + }); + }); + }, + { immediate: true }, +); + const hasData = computed(() => props.result.columns.length > 0); const columnTypeMap = computed(() => { @@ -1971,15 +2017,36 @@ const displayItems = computed(() => { watch( () => displayItems.value.length, - () => { + (length) => { + const startedAt = performance.now(); + console.info("[DBX][DataGrid:display-items:ready]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + displayItemCount: length, + sourceRowCount: props.result.rows.length, + elapsedSinceSetup: dataGridElapsed(), + }); nextTick(() => { const scrollerEl = gridRef.value?.querySelector(".data-grid-scroller"); if (scrollerEl) { updateGridScrollbarGutter(scrollerEl); updateGridHorizontalViewport(scrollerEl); } + requestAnimationFrame(() => { + const renderedRows = gridRef.value?.querySelectorAll(".vue-recycle-scroller__item-view").length; + console.info("[DBX][DataGrid:display-items:first-frame]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + displayItemCount: length, + renderedRows, + elapsed: `${Math.round(performance.now() - startedAt)}ms`, + elapsedSinceSetup: dataGridElapsed(), + loading: props.loading, + }); + }); }); }, + { immediate: true }, ); interface SearchMatch { @@ -4158,12 +4225,27 @@ watch( () => props.loading, (isLoading) => { clearInterval(_loadingTimer); + console.info(isLoading ? "[DBX][DataGrid:loading:start]" : "[DBX][DataGrid:loading:stop]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + elapsedSinceSetup: dataGridElapsed(), + }); if (isLoading) { _loadingStart = Date.now(); loadingElapsed.value = 0; _loadingTimer = setInterval(() => { loadingElapsed.value = Date.now() - _loadingStart; }, 100); + } else { + nextTick(() => { + requestAnimationFrame(() => { + console.info("[DBX][DataGrid:loading:stop:first-frame]", { + traceId: dataGridTraceId, + cacheKey: props.cacheKey, + elapsedSinceSetup: dataGridElapsed(), + }); + }); + }); } }, ); diff --git a/apps/desktop/src/components/layout/AppTabBar.vue b/apps/desktop/src/components/layout/AppTabBar.vue index 37812f0b0..c5ec3ac28 100644 --- a/apps/desktop/src/components/layout/AppTabBar.vue +++ b/apps/desktop/src/components/layout/AppTabBar.vue @@ -153,8 +153,8 @@ const showPinnedDataTabsMenu = computed( const dataTabMenuItems = computed(() => dataTabs.value.map((tab) => ({ value: tab.id, - label: tabDisplayTitle(tab), - title: tabDisplayTitle(tab), + label: tabDisplayTitle(tab, t), + title: tabDisplayTitle(tab, t), icon: Table2, iconClass: "text-emerald-600 dark:text-emerald-400", })), @@ -248,7 +248,7 @@ const dataTabsMenuContainerClass = computed(() => - {{ tabDisplayTitle(tab) }} + {{ tabDisplayTitle(tab, t) }}