perf: memoize dispatch timeline segments + load/capacity as computed Maps
Before: techDayJobsWithTravel(tech), periodLoadH(tech), techPeriodCapacityH(tech) were called as functions in the template v-for — recalculated on EVERY render for every tech (10 techs × 3 functions = 30 expensive recomputations per render). After: Pre-computed as Vue computed Maps (segmentsMap, loadMap, capMap) that only recompute when their reactive dependencies actually change. Template reads from map[tech.id] — instant O(1) lookup, no recalculation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fd326ac52e
commit
a9f8d0c7bf
|
|
@ -155,6 +155,23 @@ const hourTicks = computed(() => {
|
||||||
const isCalView = computed(() => currentView.value === 'week')
|
const isCalView = computed(() => currentView.value === 'week')
|
||||||
const unassignDropActive = ref(false)
|
const unassignDropActive = ref(false)
|
||||||
|
|
||||||
|
// Pre-compute expensive per-tech data (memoized — avoids recalculating on every render)
|
||||||
|
const segmentsMap = computed(() => {
|
||||||
|
const map = {}
|
||||||
|
for (const tech of filteredResources.value) map[tech.id] = techDayJobsWithTravel(tech)
|
||||||
|
return map
|
||||||
|
})
|
||||||
|
const loadMap = computed(() => {
|
||||||
|
const map = {}
|
||||||
|
for (const tech of filteredResources.value) map[tech.id] = periodLoadH(tech)
|
||||||
|
return map
|
||||||
|
})
|
||||||
|
const capMap = computed(() => {
|
||||||
|
const map = {}
|
||||||
|
for (const tech of filteredResources.value) map[tech.id] = techPeriodCapacityH(tech)
|
||||||
|
return map
|
||||||
|
})
|
||||||
|
|
||||||
const { pushUndo, performUndo } = useUndo(store, invalidateRoutes)
|
const { pushUndo, performUndo } = useUndo(store, invalidateRoutes)
|
||||||
|
|
||||||
const smartAssign = (job, newTechId, dateStr) => store.smartAssign(job.id, newTechId, dateStr)
|
const smartAssign = (job, newTechId, dateStr) => store.smartAssign(job.id, newTechId, dateStr)
|
||||||
|
|
@ -501,8 +518,8 @@ provide('onRenameTag', onRenameTag)
|
||||||
provide('onDeleteTag', onDeleteTag)
|
provide('onDeleteTag', onDeleteTag)
|
||||||
provide('selectedJob', selectedJob)
|
provide('selectedJob', selectedJob)
|
||||||
provide('hoveredJobId', hoveredJobId)
|
provide('hoveredJobId', hoveredJobId)
|
||||||
provide('periodLoadH', periodLoadH)
|
provide('periodLoadH', (tech) => loadMap.value[tech.id] ?? 0)
|
||||||
provide('techPeriodCapacityH', techPeriodCapacityH)
|
provide('techPeriodCapacityH', (tech) => capMap.value[tech.id] ?? 8)
|
||||||
provide('techDayEndH', techDayEndH)
|
provide('techDayEndH', techDayEndH)
|
||||||
provide('isJobMultiSelected', isJobMultiSelected)
|
provide('isJobMultiSelected', isJobMultiSelected)
|
||||||
provide('btColW', btColW)
|
provide('btColW', btColW)
|
||||||
|
|
@ -766,7 +783,7 @@ onUnmounted(() => { document.removeEventListener('keydown', onKeyDown); document
|
||||||
Aucune ressource. <button class="sbf-primary-btn" style="display:inline-block;margin-left:0.75rem" @click="clearFilters">Réinitialiser</button>
|
Aucune ressource. <button class="sbf-primary-btn" style="display:inline-block;margin-left:0.75rem" @click="clearFilters">Réinitialiser</button>
|
||||||
</div>
|
</div>
|
||||||
<TimelineRow v-for="tech in filteredResources" :key="tech.id"
|
<TimelineRow v-for="tech in filteredResources" :key="tech.id"
|
||||||
:tech="tech" :segments="techDayJobsWithTravel(tech)"
|
:tech="tech" :segments="segmentsMap[tech.id] || []"
|
||||||
:hour-ticks="hourTicks" :total-w="totalW" :px-per-hr="pxPerHr"
|
:hour-ticks="hourTicks" :total-w="totalW" :px-per-hr="pxPerHr"
|
||||||
:h-start="H_START" :h-end="H_END" :row-h="ROW_H"
|
:h-start="H_START" :h-end="H_END" :row-h="ROW_H"
|
||||||
:is-selected="selectedTechId===tech.id"
|
:is-selected="selectedTechId===tech.id"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user