Skip to content

Commit b4bd857

Browse files
authored
Merge pull request #293 from vue-pivottable/fix/memory-leak-issue-270
fix: optimize memory usage and remove unnecessary code
2 parents d9edef8 + a80fab8 commit b4bd857

File tree

6 files changed

+37
-193
lines changed

6 files changed

+37
-193
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"vue-pivottable": patch
3+
---
4+
5+
Fix main.ts import reference issue and optimize memory usage
6+
7+
Fixed undefined SimpleApp reference to use App component in main.ts entry point. This resolves runtime errors and improves application startup reliability.

src/components/pivottable-ui/VPivottableUi.vue

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ import VRendererCell from './VRendererCell.vue'
137137
import VAggregatorCell from './VAggregatorCell.vue'
138138
import VDragAndDropCell from './VDragAndDropCell.vue'
139139
import VPivottable from '../pivottable/VPivottable.vue'
140-
import { computed, watch, shallowRef, watchEffect, onUnmounted } from 'vue'
140+
import TableRenderer from '../pivottable/renderer'
141+
import { computed, watch, toRaw } from 'vue'
141142
import {
142143
usePropsState,
143144
useMaterializeInput,
@@ -182,6 +183,7 @@ const props = withDefaults(
182183
>(),
183184
{
184185
aggregators: () => defaultAggregators,
186+
renderers: () => TableRenderer,
185187
hiddenAttributes: () => [],
186188
hiddenFromAggregators: () => [],
187189
pivotModel: undefined,
@@ -291,9 +293,10 @@ const { allFilters, materializedInput } = useMaterializeInput(
291293
)
292294
293295
const rendererItems = computed(() =>
294-
Object.keys(state.renderers).length ? state.renderers : {}
296+
state.renderers && Object.keys(state.renderers).length ? state.renderers : {}
295297
)
296298
const aggregatorItems = computed(() => state.aggregators)
299+
297300
const rowAttrs = computed(() => {
298301
return state.rows.filter(
299302
(e) =>
@@ -327,38 +330,11 @@ const unusedAttrs = computed(() => {
327330
.sort(sortAs(pivotUiState.unusedOrder))
328331
})
329332
330-
// Use shallowRef instead of computed to prevent creating new PivotData instances on every access
331-
const pivotData = shallowRef(new PivotData(state))
332-
333-
// Update pivotData when state changes, and clean up the watcher
334-
const stopWatcher = watchEffect(() => {
335-
// Clean up old PivotData if exists
336-
const oldPivotData = pivotData.value
337-
pivotData.value = new PivotData(state)
338-
339-
// Clear old data references
340-
if (oldPivotData) {
341-
oldPivotData.tree = {}
342-
oldPivotData.rowKeys = []
343-
oldPivotData.colKeys = []
344-
oldPivotData.rowTotals = {}
345-
oldPivotData.colTotals = {}
346-
oldPivotData.filteredData = []
347-
}
348-
})
349-
350-
// Clean up on unmount
351-
onUnmounted(() => {
352-
stopWatcher()
353-
if (pivotData.value) {
354-
pivotData.value.tree = {}
355-
pivotData.value.rowKeys = []
356-
pivotData.value.colKeys = []
357-
pivotData.value.rowTotals = {}
358-
pivotData.value.colTotals = {}
359-
pivotData.value.filteredData = []
360-
}
361-
})
333+
const pivotData = computed(() => new PivotData({
334+
...state,
335+
data: toRaw(state.data),
336+
aggregators: toRaw(state.aggregators)
337+
}))
362338
const pivotProps = computed(() => ({
363339
data: state.data,
364340
aggregators: state.aggregators,
@@ -408,22 +384,19 @@ watch(
408384
} as Partial<typeof state>)
409385
}
410386
},
411-
{ deep: true, immediate: true }
387+
{ immediate: true }
412388
)
413389
414390
watch(
415-
[allFilters, materializedInput],
391+
materializedInput,
416392
() => {
417-
// Only update the changed properties, not the entire state
393+
// Only update data when materializedInput changes
418394
updateMultiple({
419-
allFilters: allFilters.value,
420-
materializedInput: materializedInput.value,
421-
data: materializedInput.value // Ensure data is also updated
395+
data: materializedInput.value
422396
})
423397
},
424398
{
425-
immediate: true // Add immediate to ensure initial update
426-
// Removed deep: true - this was causing 80% of memory leak
399+
immediate: true
427400
}
428401
)
429402
</script>

src/composables/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ export { useProvideFilterBox, provideFilterBox } from './useProvideFilterbox'
33
export { useMaterializeInput } from './useMaterializeInput'
44
export { usePropsState } from './usePropsState'
55
export { usePivotUiState } from './usePivotUiState'
6-
export { usePivotData } from './usePivotData'
7-
export { usePivotModelHistory } from './usePivotModelHistory'
6+
export { usePivotData } from './usePivotData'

src/composables/useMaterializeInput.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Ref, ref, watch } from 'vue'
1+
import { Ref, ref, watch, shallowRef, ShallowRef, onUnmounted } from 'vue'
22
import { PivotData } from '@/helper'
33

44
export interface UseMaterializeInputOptions {
@@ -7,8 +7,8 @@ export interface UseMaterializeInputOptions {
77

88
export interface UseMaterializeInputReturn {
99
rawData: Ref<any>
10-
allFilters: Ref<Record<string, Record<string, number>>>
11-
materializedInput: Ref<any[]>
10+
allFilters: ShallowRef<Record<string, Record<string, number>>>
11+
materializedInput: ShallowRef<any[]>
1212
processData: (data: any) => { AllFilters: Record<string, Record<string, number>>; materializedInput: any[] } | void
1313
}
1414

@@ -17,8 +17,9 @@ export function useMaterializeInput (
1717
options: UseMaterializeInputOptions
1818
): UseMaterializeInputReturn {
1919
const rawData = ref<any>(null)
20-
const allFilters = ref<Record<string, Record<string, number>>>({})
21-
const materializedInput = ref<any[]>([])
20+
// Use shallowRef to prevent deep reactivity on large objects
21+
const allFilters = shallowRef<Record<string, Record<string, number>>>({})
22+
const materializedInput = shallowRef<any[]>([])
2223

2324
function processData (data: any) {
2425
if (!data || rawData.value === data) return
@@ -74,6 +75,12 @@ export function useMaterializeInput (
7475
}
7576
)
7677

78+
onUnmounted(() => {
79+
allFilters.value = {}
80+
materializedInput.value = []
81+
rawData.value = null
82+
})
83+
7784
return {
7885
rawData,
7986
allFilters,

src/composables/usePivotModelHistory.ts

Lines changed: 0 additions & 137 deletions
This file was deleted.

src/main.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { createApp } from 'vue'
2+
import App from './App.vue'
23

3-
// import App from './App.vue'
4-
import SimpleApp from './SimpleApp.vue'
5-
// import VuePivottable from '@/'
6-
7-
const app = createApp(SimpleApp)
8-
9-
// app.component('VuePivottableUi', VuePivottableUi)
4+
const app = createApp(App)
105

116
app.mount('#app')

0 commit comments

Comments
 (0)