똑같은 삽질은 2번 하지 말자
Vue의 성능문제 본문
개요
성능문제 빠져서 디버그를 하면서 어느부분이 문제였는지를 파헤쳤던 경험을 적어보고자 한다.
<script>
...
export default {
data() {
return {
...
};
},
computed: {
groupedFilterItems() {
if (!this.reportData?.filterItems) return [];
const groupedItems = [];
const overGroupingKoumokuIds = new Set();
const clonedItems = [...this.reportData.filterItems];
clonedItems.forEach(item => {
if (overGroupingKoumokuIds.has(item.koumokuId)) return;
const isGroupType =
item.koumokuType === KoumokuType.Date ||
[KoumokuType.SelectDetail, KoumokuType.SelectButton].includes(item.koumokuType);
if (!isGroupType) {
groupedItems.push(item);
} else {
const sameItems = clonedItems.filter(i => i.koumokuId === item.koumokuId);
groupedItems.push({
filterItemsId: item.filterItemsId,
koumokuId: item.koumokuId,
koumokuType: item.koumokuType,
displayKoumokuName: item.displayKoumokuName,
items: sameItems, // 이 부분 주의
});
}
overGroupingKoumokuIds.add(item.koumokuId);
});
return groupedItems.sort((a, b) => a.filterItemsId - b.filterItemsId);
},
},
methods: {
...
updateSelectItem(item, values) {
const newFilterItems = values.map(value => {
const [key1, key2, key3, key4, key5] = value.split('_');
return {
...item, // 여기서 items도 안에 들어가게 된다.
periodType: null,
key1: Number(key1) || null,
key2: Number(key2) || null,
key3: Number(key3) || null,
key4: Number(key4) || null,
key5: Number(key5) || null,
defaultDatePeriodId: null,
};
});
if (newFilterItems.length === 0) {
newFilterItems.push({
...item,
key1: null,
key2: null,
key3: null,
key4: null,
key5: null,
});
}
const baseFilterItems = this.reportData.filterItems.filter(x => x.koumokuId !== item.koumokuId);
const updatedFilterItems = [...baseFilterItems, ...newFilterItems];
this.$emit('updateReportData', {
...this.reportData,
filterItems: updatedFilterItems,
});
},
...
},
</script>
- groupedFilterItems에서 같은 아이템들을 그룹으로 묶어서 묶인 아이템들은 filterItem의 items안에 보관
- updateSelectItem에서 새로운 filterItem를 생성할 때 filterItem안에 items가 들어간다.
- 다시 groupedFilterItems가 실행되며 filterItems의 items의 하나의 item에도 items가 들어가 버린다. 이러면 filterItem을 추가할 때마다 필요없는 중첩된 데이트가 제곱수로 늘어나게 되어서 화면의 성능이 상당히 나빠졌었다.
해결 뒤 코드
<script>
export default {
...
computed: {
groupedFilterItems() {
...변경없음
},
...
},
methods: {
...
updateSelectItem(item, values) {
const targetFilterItem = {
filterItemsId: item.filterItemsId,
koumokuId: item.koumokuId,
koumokuType: item.koumokuType,
displayKoumokuName: item.displayKoumokuName,
key1: null,
key2: null,
key3: null,
key4: null,
key5: null,
periodType: null,
defaultDatePeriodId: null,
};
const newFilterItems = values.map(value => {
const [key1, key2, key3, key4, key5] = value.split('_');
return {
...targetFilterItem,
periodType: null,
key1: Number(key1) || null,
key2: Number(key2) || null,
key3: Number(key3) || null,
key4: Number(key4) || null,
key5: Number(key5) || null,
defaultDatePeriodId: null,
};
});
if (newFilterItems.length === 0) {
newFilterItems.push(targetFilterItem);
}
const baseFilterItems = this.reportData.filterItems.filter(x => x.koumokuId !== item.koumokuId);
const updatedFilterItems = [...baseFilterItems, ...newFilterItems];
this.$emit('updateReportData', {
...this.reportData,
filterItems: updatedFilterItems,
});
},
...
},
};
</script>
결론
복잡한 데이터를 다룰 때 필요없는 데이터를 양산하고 있지 않는지를 체크해보자
Comments