아주 작은 프로젝트라 크게 신경 쓸 경우는 없겠지만 만약 사이즈가 커지면 렌더링 개선이 필요하게 될것입니다.
개선점을 찾기전 Vue Devtools를 알아보고 가겠습니다.
Vue.js로 개발하는 경우 디버그를 도와주는 툴입니다.
https://github.com/vuejs/vue-devtools
다운로드
위 사진을 보시면 저희가 했던 Todo프로젝트에 할일을 추가하기 위해 달리기하기 를 입력했을 뿐인데, 컴포넌트 내부에서 처리되는(라이프 사이클) 시간과 횟수가 저희가 생각한것보다 많은걸 볼수 있습니다.
이는 input값이 바뀌면서 화면 전체의 Button을 전부 다시 재 랜더링 하면서 나오는 결과로 어떻게 하면 input만 업데이트 할수 있을지 고민하게 되었습니다.
TodoList부분에 개선할 점이 있다는 것을 발견하였습니다.
코드를 보니 V-for로 반복되어 랜더링 되는 부분임을 확인할 수 있었습니다.
//HelloWorld.vue
<li class="todo-item" v-bind:key="index" v-for="(todo, index) in $store.state.todoList">
<p class="text">{{ todo.text }}</p>
<el-button v-if="todo.completed" @click="compelete(index)" class="complete completed">Complete</el-button>
<el-button v-else @click="compelete(index)" class="complete">Complete</el-button>
<el-button @click="deleteTodo(index)" class="delete">Delete</el-button>
</li>
개선하기 위해 TodoList를 랜더링 해주는 부분을 따로 때어내서 컴포넌트 파일을 만들어 주겠습니다.
//TheListItems.vue
<template>
<div>
<li class="todo-item" v-bind:key="index" v-for="(todo, index) in $store.state.todoList">
<p class="text">{{ todo.text }}</p>
<el-button v-if="todo.completed" @click="compelete(index)" class="complete completed">Complete</el-button>
<el-button v-else @click="compelete(index)" class="complete">Complete</el-button>
<el-button @click="deleteTodo(index)" class="delete">Delete</el-button>
</li>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class extends Vue {
compelete(index: number) {
console.log("compelete");
this.$store.commit("compelete", index);
}
deleteTodo(index: number) {
console.log("삭제");
this.$store.commit("deleteTodo", index);
}
}
</script>
<style scoped lang="scss">
.todo-container {
.el-input {
width: 300px;
}
.complete.completed {
background-color: #409eff;
}
}
</style>
반복적으로 랜더링 되는 부분을 TheListItems.vue로 컴포넌트화 해 작성하였습니다.
이 컴포넌트를 기존에 컴포넌트에 적용해주시면 됩니다.
//HelloWorld.vue
<template>
<el-card class="todo-container">
<h2>Todo List</h2>
<form>
<el-input placeholder="Please input" v-model="input"></el-input>
<el-button type="primary" @click="addTodo(input)">Add Todo</el-button>
</form>
<ul>
<TheListItems /> //컴포넌트 등록
<p class="text">{{ todo.text }}</p>
<el-button
v-if="todo.completed"
@click="compelete(index)"
class="complete completed"
>Complete</el-button>
<el-button v-else @click="compelete(index)" class="complete">Complete</el-button>
<el-button @click="deleteTodo(index)" class="delete">Delete</el-button>
</li>-->
</ul>
</el-card>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import TheListItems from "./TheListItems.vue";//컴포넌트 불러오기
interface TodosType {
text?: string;
completed?: boolean;
}
//컴포넌트 등록
@Component({
components: { TheListItems }
})
export default class HelloWorld extends Vue {
input?: string = "";
addTodo(text: string) {
console.log("addTodo");
this.$store.commit("addTodo", text);
}
</script>
<style scoped lang="scss">
.todo-container {
.el-input {
width: 300px;
}
.complete.completed {
background-color: #409eff;
}
}
</style>
위 처럼 개선을 한뒤 전과 같이 "달리기하기"를 입력하였을 때 현저히 랜더링 해주는 횟수가 줄어든 것을 볼수 있습니다.
이번 포스팅에서는 Vue Devtools를 활용하여 개선점을 찾고 개선하는 법을 알아보있습니다.