Devhyun

메뉴

현재 화면 위치

데브현 메인 블로그 포스트

타이틀

Vue Devtools 퍼포먼스 개선 포인트 찾기

2019.12.09
핫한 길다란

아래는 Qiita에 개재된 「Vue Devtoolsでパフォーマンス改善ポイントを見つける」를 번역한 내용입니다.

다소 의역이 있어 어색한 부분이 있어도 양해 부탁드립니다. 🙉

원문 보기

이 포스팅은 Vue.js Advent Calendar 2019 #18 번째 글입니다.

VueDevtools의 Performance탭을 사용하여 퍼포먼스 개선 포인트를 쉽게 발견하는 방법을 소개하고 싶다고 생각했습니다.

발견한 개선 포인트에서 실제로 퍼포먼스를 개선하는 예를 소개하겠습니다.

Vue Devtools란

Vue.js로 개발하는 경우 디버그를 도와주는 툴입니다.

vuejs/vue-devtools

Chrome Extension으로 배포되어 있습니다.
다양한 탭이 있지만, 이번에는 Performance 탭을 사용하겠습니다.

Vue Devtools에 대해서 상세한 정보는 아래의 포스팅을 참고해주세요.

Vue Devtools로 최적화된 디버깅하기 - 일본어 원문

Performance 탭

Vue.js로 개발된 애플리케이션의 퍼포먼스를 간단하게 측정하는 기능입니다.

Chrome DevTools를 사용하여 측정하면 상세하게 알 수 없지만, 어렵지 않고 간단하게 사용할 수 있다는 인상이 있습니다.

퍼포먼스가 안 좋은 컴포넌트를 쉽고 빠르게 발견하고 싶은 경우 이 Performance 탭을 사용하는 것을 추천합니다.

Performance탭을 사용하는 방법에 대해서도 위의 포스팅을 참고해주세요.

Vue Devtools로 퍼포먼스 개선 포인트를 찾기

Vue Devtools의 Performance 탭을 사용하여 퍼포먼스 개선 포인트를 찾아봅시다.

대상 컴포넌트

개선대상 컴포넌트는 아래와 같은 조건이라 가정해보겠습니다.

  • 대량의 선택지로부터 한 개를 선택하는 다이얼로그 컴포넌트
  • 선택지에 마우스를 호버하면 그 선택지의 설명이 아래와 같은 방법으로 표시

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_63950_5355c19b-c038-db25-7cbf-66dcfe4f053a.gif

실제로 동작하는 배포된 애플리케이션 데모 주소입니다.
https://vue-devtools-performance-handson.netlify.com

아래는 컴포넌트의 깃허브 레파지토리입니다.
https://github.com/shun91/vue-devtools-performance-handson/blob/master/src/components/HeavyDialog.vue

동작이 둔한 느낌

위의 화면이나 데모에서도 보셨다시피 이 다이얼로그는 동작이 둔하고 무겁게 느껴집니다.

우선, 버튼을 클릭하고 나서 다이얼로그가 열리기까지 느리고, 애니메이션도 둔탁한 느낌입니다. 게다가 마우스를 호버하여 선택지의 배경색이 바뀌지만, 이 애니메이션 또한 느리게 작동하고 있습니다.

퍼포먼스 측정

그럼, 실제로 Vue Devtools의 Performance 탭을 사용하여 퍼포먼스를 측정해봅시다.
이번에는 선택지에 마우스를 호버했을 경우 퍼포먼스를 확인해보겠습니다.

먼저, Frames per second를 확인하겠습니다.
아래의 화면을 보면 선택지에 마우스를 호버하는 순간 fps가 확 떨어지는 것을 알 수 있습니다.

vd2.gif

계속해서 Component render를 확인해보겠습니다.
이쪽도 선택지에 마우스를 호버했을 때 무언가 많이 render 처리가 되고 있는 걸 알 수 있습니다.

vd3.gif

개선 포인트 찾기

측정결과를 좀 더 상세히 살펴봅시다.

Component render에서 좌측의 컴포넌트 이름을 클릭하면, 그 컴포넌트 내부가 처리(라이프 사이클 훅)되는 시간과 횟수를 확인할 수 있습니다.

예를 들어, <VListTitle>을 클릭하면 아래와 같습니다.

vd4.jpg

선택지에 마우스 호버한것뿐인데 updateRender가 600번이나 실행되어 전체 71333ms(약 71초)가 걸렸다는것을 알 수 있었습니다.

<Vradio><VIcon>도 똑같이 updateRender가 600번이나 실행되고 있습니다.

즉, <VListTitle>, <Vradio>, <VIcon>에는 퍼포먼스 개선이 필요하다고 판단됩니다.

이처럼, Performance 탭을 사용하면 퍼포먼스가 안 좋은 컴포넌트를 간단하게 발견할 수 있습니다.

이 포스팅의 목적은 포인트를 찾는 방법이지만, 이왕이면 실제로 퍼포먼스를 개선해보도록 하겠습니다.

개선 진행

<VListTitle>, <Vradio>, <VIcon>에 개선 포인트가 있다는 것을 발견하였습니다.

코드를 확인해보면 v-for로 반복되어 랜더링 되어, 선택지 하나하나로 구성되어있는 요소임을 알 수 있습니다.

<v-list-tile
  v-for="{ value } in items"
  :key="value"
  ripple
  @click="selected = value"
  @mouseenter="updateOnmoused(value)"
  @mouseleave="updateOnmoused('')"
>
  <v-list-tile-action>
    <v-radio :value="value"  data-tomark-pass />
  </v-list-tile-action>

  <v-list-tile-content>
    <v-list-tile-title>{{ value }}</v-list-tile-title>
  </v-list-tile-content>
</v-list-tile>

하나의 선택지에 마우스를 호버하는것만으로 600번도 넘게 랜더 처리되는 것은, 해당 액션에 대해 모든 <VListTitle>, <Vradio>, <VIcon> 컴포넌트가 다시 랜더링 되고 있다는 가능성이 있습니다.

이러한 부분은 불필요한 랜더링이 이뤄지고 있고 마우스 호버한 부분만 다시 랜더링 하면 충분합니다.

재 랜더링되는 부분을 컴포넌트화

불필요한 랜더링을 방지하기 위해서는 해당부분을 컴포넌트화하는 방법이 있습니다.
상세한 것은 아래의 포스팅을 참고해 주세요.

컴포넌트를 사용하여 랜더링 갱신 비용을 줄이자 - 일본어 원문

그럼 <VListTitle>의 부분을 <TheListItem>이라는 별칭의 컴포넌트로 분리해 보겠습니다.

diff --git a/src/components/HeavyDialog.vue b/src/components/HeavyDialog.vue
index cd89f9c..8297e4c 100644
--- a/src/components/HeavyDialog.vue
+++ b/src/components/HeavyDialog.vue
@@ -1,7 +1,7 @@
 <template>
   <v-dialog v-model="dialog" scrollable max-width="300px">
     <template #activator="{ on }">
-      <v-btn v-on="on" dark>open heavy dialog</v-btn>
+      <v-btn v-on="on">open light dialog</v-btn>
     </template>

     <v-card>
@@ -12,22 +12,14 @@
       <v-card-text class="pa-0" style="height: 300px;">
         <v-radio-group v-model="selected">
           <v-list class="pa-0">
-            <v-list-tile
-              v-for="{ value } in items"
-              :key="value"
-              ripple
-              @click="selected = value"
-              @mouseenter="updateOnmoused(value)"
+            <the-list-item
+              v-for="item in items"
+              :key="item.value"
+              :item="item"
+              @click="selected = item.value"
+              @mouseenter="updateOnmoused(item.value)"
               @mouseleave="updateOnmoused('')"
-            >
-              <v-list-tile-action>
-                <v-radio :value="value"  data-tomark-pass />
-              </v-list-tile-action>
-
-              <v-list-tile-content>
-                <v-list-tile-title>{{ value }}</v-list-tile-title>
-              </v-list-tile-content>
-            </v-list-tile>
+            />
           </v-list>
         </v-radio-group>
       </v-card-text>
@@ -45,8 +37,11 @@

 <script lang="ts">
 import Vue from "vue";
+import TheListItem from "./TheListItem.vue";

 export default Vue.extend({
+  components: { TheListItem },
+
   data: () => ({
     dialog: false,
     selected: "",

변경 후 코드는 LightDialog.vue로 저장하였습니다.

<TheListItem>의 코드는 아래와 같습니다.

<template>
  <v-list-tile
    ripple
    @click="$emit('click')"
    @mouseenter="$emit('mouseenter')"
    @mouseleave="$emit('mouseleave')"
  >
    <v-list-tile-action>
      <v-radio :value="item.value"  data-tomark-pass />
    </v-list-tile-action>

    <v-list-tile-content>
      <v-list-tile-title>{{ item.value }}</v-list-tile-title>
    </v-list-tile-content>
  </v-list-tile>
</template>

<script lang="ts">
import Vue, { PropType } from "vue";

export default Vue.extend({
  props: { item: { type: Object as PropType<any>, required: true } }
});
</script>

개선 후 퍼포먼스 측정

코드를 수정하여 다시 한번 퍼포먼스를 측정해보겠습니다.

우선은 Frames per second 입니다.
훌륭하게도 60fps를 유지하게 되었습니다 !

vd5.gif

계속해서 Component render 입니다.
<VListTitle>은 단 1번만 다시 랜더링 되고 있습니다.

vd6.gif

개선 전후를 비교해보면 확실하게 동작이 최적화된 느낌을 알 수 있습니다.
데모를 통해 확인해주세요.

Before After
vd7.gif vd8.gif

마치며

이번 포스팅에서는 Vue Devtools의 Performance 탭을 사용하여 퍼포먼스 개선 포인트를 찾는 방법을 소개하였습니다.
더 나아가, 발견한 개선 포인트를 수정하여 실제로 퍼포먼스를 개선해보았습니다.

  • Performance탭을 사용하면 퍼포먼스가 안 좋은 컴포넌트를 쉽게 발견할 수 있다.
  • Chrome DevTools를 사용하여 측정하면 간단하게는 알 수 있지만 아주 쉽고 간단하게 사용할 수 있다.

또한, 이번에 사용했던 코드는 아래의 레파지토리에서 확인하실 수 있습니다.
shun91/vue-devtools-performance-handson
https://github.com/shun91/vue-devtools-performance-handson

읽어주셔서 감사합니다 ! mm

역주

프론트엔드 공부를 하면서 가장 어렵게 느껴졌던 부분이 컴포넌트 최적화 부분이라고 생각합니다.
아직은 컴포넌트를 설계하면서 성능 최적화를 고려하기엔 부족하기 때문에, 다양한 툴을 활용하여 퍼포먼스를 확인하고 문제점을 발견해가면서 코드를 개선하는 방법이 좋은 공부법이라고 생각합니다. 😀

0개의 댓글

로그인을 하시면 댓글을 작성할 수 있어요 !
목록으로 가기