Skip to content

Commit 8d3ee58

Browse files
committed
improve initial mount performance for groupedtimeentrytable by streaming in the rows
mounting the rows mounts lots of nested components which results in a delay on the initial mount.
1 parent 8a2c260 commit 8d3ee58

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

resources/js/packages/ui/src/TimeEntry/TimeEntryGroupedTable.vue

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { computed } from 'vue';
2+
import { computed, onMounted, ref, watch } from 'vue';
33
import type {
44
CreateClientBody,
55
CreateProjectBody,
@@ -38,6 +38,8 @@ const props = defineProps<{
3838
canCreateProject: boolean;
3939
}>();
4040
41+
const maxVisibleGroups = ref(7); // Start with 10 day groups, then show all
42+
4143
const groupedTimeEntries = computed(() => {
4244
const groupedEntriesByDay: Record<string, TimeEntry[]> = {};
4345
for (const entry of props.timeEntries) {
@@ -94,6 +96,7 @@ const groupedTimeEntries = computed(() => {
9496
9597
groupedEntriesByDayAndType[dailyEntriesKey] = newDailyEntries;
9698
}
99+
97100
return groupedEntriesByDayAndType;
98101
});
99102
@@ -134,11 +137,43 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
134137
);
135138
});
136139
}
140+
141+
const visibleGroupedEntries = computed(() => {
142+
const allGroups = Object.entries(groupedTimeEntries.value);
143+
return Object.fromEntries(allGroups.slice(0, maxVisibleGroups.value));
144+
});
145+
146+
const totalGroups = computed(() => Object.keys(groupedTimeEntries.value).length);
147+
148+
function startProgressiveLoading() {
149+
const loadMoreGroups = () => {
150+
if (maxVisibleGroups.value < totalGroups.value) {
151+
maxVisibleGroups.value = Math.min(maxVisibleGroups.value + 5, totalGroups.value);
152+
153+
if (maxVisibleGroups.value < totalGroups.value) {
154+
requestIdleCallback(loadMoreGroups);
155+
}
156+
}
157+
};
158+
159+
requestIdleCallback(loadMoreGroups);
160+
}
161+
162+
// Watch for changes to totalGroups and adjust maxVisibleGroups accordingly
163+
watch(totalGroups, (newTotal, oldTotal) => {
164+
if (newTotal !== oldTotal) {
165+
maxVisibleGroups.value = newTotal;
166+
}
167+
});
168+
169+
onMounted(() => {
170+
startProgressiveLoading();
171+
});
137172
</script>
138173

139174
<template>
140175
<div class="@container">
141-
<div v-for="(value, key) in groupedTimeEntries" :key="key">
176+
<div v-for="(value, key) in visibleGroupedEntries" :key="key">
142177
<TimeEntryRowHeading
143178
:date="key"
144179
:duration="sumDuration(value)"

0 commit comments

Comments
 (0)