요즘 브라우저 OOM(Out of Memory) 이슈를 처리하고 있다.
대량 데이터가 한꺼번에 브라우저 메모리에 로드되도록 코드가 작성되어있어 수정 중이다.
데이터 크기를 줄이는 작업과는 별개로 리팩토링이 필요한 코드를 발견하여 정리해본다.
QueryInfo 컴포넌트는 부모 컴포넌트로부터 queryList 라는 배열 형태의 props 전달 받음v-expansion-panel을 반복 생성ResultGrid 컴포넌트가 있고 이 컴포넌트는 gridOption 을 props 로 전달받음gridOption은 action.mkOption(item) function을 호출하여 생성<template>
<v-expansion-panels>
<v-expansion-panel
v-for="item in queryList"
:key="item.id"
>
<v-expansion-panel-header>
{{ item.title }}
</v-expansion-panel-header>
<v-expansion-panel-content>
<ResultGrid v-if="showGrid"
:grid-option="action.mkOption(item)" />
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</template>
<script lang="ts">
export default defineComponent({
name: 'QueryInfo',
props: {
queryList: {
type: Array,
default: () => [],
},
...
}
setup(props: Props) {
const action = {
mkOption(data: string): Grid.Options {
// 매우 오래 걸리는 연산
}
}
return {
action,
...
};
}
</script>
gridOption은 queryList 가 setup 됐을 때 한번만 연산해주면 되는 값이다.ResultGrid의 v-if 조건이 변경될 때마다action.mkOption(item)이 호출되고 있었다. ⇒ ResultGrid가 mount/unmount 될 때마다 실행하기 때문gridOption을 한 번만 연산하여 사용하도록 코드를 리팩토링 해보자.
<template>
<v-expansion-panels>
<!-- queryList 대신 computedQueryList -->
<v-expansion-panel
v-for="item in computedQueryList"
:key="item.id"
>
<v-expansion-panel-header>
{{ item.title }}
</v-expansion-panel-header>
<v-expansion-panel-content>
<ResultGrid v-if="showGrid" :grid-option="item.gridOption" />
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</template>
<script lang="ts">
export default defineComponent({
name: 'QueryInfo',
props: {
queryList: {
type: Array,
default: () => [],
},
...
}
setup(props: Props) {
const state = reactive({
// props 의 queryList를 사용하는 computed 추가. template에서 사용.
computedQueryList: computed(() =>
props.queryList.map((query: QueryInfo) => ({
...query,
gridOption: action.mkOption(query),
}))
),
});
const action = {
mkOption(data: string): Grid.Options {
// 매우 오래 걸리는 연산
}
}
return {
...toRefs(state),
action,
...
};
}
</script>
ResultGrid가 렌더링될 때 매번 gridOption 연산하지 않음(showGrid 변경하며 확인)computed는 의존 관계가 있는 데이터에 변경이 감지됐을 때 다시 계산하기 때문에 queryList props가 변경됐을 때 action.mkOption(item)이 호출v-if로 mount/unmount가 자주 일어나는 구조라면