개발 도구 (Development Tools)/Vue

#5. Vue 3 성능 최적화

BiCute 2023. 6. 2. 08:00
반응형

 

# 렌더링 최적화

 

Vue에서 렌더링을 최적화하는 몇 가지 방법은 다음과 같습니다:

 

 

(1) 가상 DOM 활용

 

Vue에서 가상 DOM을 활용하면 실제 DOM을 추상화하여 변경된 부분만 업데이트할 수 있습니다. 아래는 가상 DOM을 사용하여 성능을 개선하는 예시입니다.

<template>
  <ul>
    <li v-for="item in items" :key="item">{{ item }}</li>
  </ul>
  <button @click="shuffle">Shuffle</button>
</template>

<script>
export default {
  data() {
    return {
      items: [1, 2, 3, 4, 5]
    };
  },
  methods: {
    shuffle() {
      this.items = this.shuffleArray(this.items);
    },
    shuffleArray(array) {
      // 배열을 셔플하는 함수
      let m = array.length,
          t, i;
      while (m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
      }
      return array;
    }
  }
};
</script>

위 코드에서는 key 속성을 사용하여 각각의 li 요소를 고유하게 식별할 수 있도록 하였습니다.

이렇게 하면 Vue가 변경된 부분을 추적하여 성능을 향상시킬 수 있습니다.

 

 

(2) 컴포넌트 분할

 

Vue에서 컴포넌트를 작은 단위로 분할하면 부분적으로 렌더링할 수 있습니다.

아래는 컴포넌트를 분할하여 성능을 개선하는 예시입니다.

<!-- ParentComponent.vue -->
<template>
  <div>
    <child-component :items="items" />
    <button @click="shuffle">Shuffle</button>
  </div>
</template>

<script>
import ChildComponent from "./ChildComponent.vue";

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      items: [1, 2, 3, 4, 5]
    };
  },
  methods: {
    shuffle() {
      this.items = this.shuffleArray(this.items);
    },
    shuffleArray(array) {
      // 배열을 셔플하는 함수
      let m = array.length,
          t, i;
      while (m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
      }
      return array;
    }
  }
};
</script>

<!-- ChildComponent.vue -->
<template>
  <ul>
    <li v-for="item in items" :key="item">{{ item }}</li>
  </ul>
</template>

<script>
export default {
  props: {
    items: Array
  }
};
</script>

위 코드에서는 ParentComponent와 ChildComponent로 컴포넌트를 분할하여, ChildComponent에서는 items 배열을 렌더링하도록 하였습니다. 이렇게 하면 shuffle 메서드가 호출될 때에도 ChildComponent만 업데이트되므로, 전체 페이지를 다시 렌더링할 필요가 없어서 성능이 향상됩니다.

 

 

(3) v-if 대신 v-show 사용

 

Vue에서 v-if는 조건부 렌더링을 할 때 사용되는데, 컴포넌트를 다시 렌더링하는 과정이 필요하기 때문에 성능이 저하될 수 있습니다.

대신 v-show를 사용하면 CSS를 이용하여 요소를 숨기고 보여줄 수 있어서, 렌더링 성능을 개선할 수 있습니다.

 

아래는 v-show를 사용하여 성능을 개선하는 예시입니다.

<template>
  <div>
    <button @click="toggle">Toggle</button>
    <div v-show="show">Hello, World!</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true
    };
  },
  methods: {
    toggle() {
      this.show = !this.show;
    }
  }
};
</script>

위 코드에서는 v-show를 사용하여 조건부 렌더링을 하였습니다.

이렇게 하면 컴포넌트를 다시 렌더링하는 과정이 필요없어서 성능이 향상됩니다.

 

 

(4) 계산된 속성(computed) 사용하기

계산된 속성을 사용하면 템플릿에서 반복적으로 로직을 처리하지 않고, 미리 계산된 값을 재사용할 수 있습니다.

이를 통해 중복 계산을 줄이고, 렌더링 속도를 개선할 수 있습니다.

<template>
  <div>
    {{ fullName }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe',
    };
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    },
  },
};
</script>

 

 

 

# 로딩 속도 최적화

 

Vue에서 로딩 속도를 최적화하는 몇 가지 방법은 다음과 같습니다:

 

 

(1) Vue 컴포넌트 코드를 비동기적으로 로드하는 방법

 

사용자가 앱을 처음 로드할 때 모든 컴포넌트를 로드하려고 할 때, 초기 로딩 시간이 길어질 수 있습니다. 이를 개선하기 위해, 컴포넌트 코드를 필요할 때 비동기적으로 로드할 수 있습니다.

const MyComponent = () => import('./MyComponent.vue');

import() 함수를 사용하여 MyComponent.vue 파일을 비동기적으로 로드할 수 있습니다.

이를 사용하면 사용자가 컴포넌트가 필요한 시점에만 로드하도록 할 수 있습니다.

 

 

(2) 이미지 최적화

 

이미지 크기를 최적화하고 이미지를 적절히 압축하여 로딩 속도를 개선할 수 있습니다. 이미지 크기를 최적화하는 방법으로는 이미지 포맷 변경, 이미지 사이즈 조정, 이미지 크롭 등이 있습니다.

<img src="image.jpg" alt="image" width="300" height="200">

 

 

(3) 최적화된 라이브러리 사용

 

라이브러리를 최적화하여 불필요한 부분을 제거할 수 있습니다.

이렇게 하면 파일 크기를 줄이고 로딩 속도를 개선할 수 있습니다. 최적화된 라이브러리는 보통 ***.min.js 형식의 파일 이름을 가지고 있습니다

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js"></script>

 

 

 

# 메모리 최적화

 

Vue에서 메모리 최적화를 위한 몇 가지 방법은 다음과 같습니다:

 

 

(1) 메모리 누수 방지

 

Vue 컴포넌트의 생명주기 훅을 이용하여 메모리 누수를 방지할 수 있습니다. 예를 들어, 이벤트 리스너를 등록할 때 mounted 훅에서 등록하고, unmounted 훅에서 제거할 수 있습니다. 예를 들어, 다음과 같이 사용할 수 있습니다.

<template>
  <div>
    <button @click="startCountdown">Start</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      countdownInterval: null,
      count: 10
    }
  },
  methods: {
    startCountdown() {
      this.countdownInterval = setInterval(() => {
        this.count -= 1
      }, 1000)
    },
    stopCountdown() {
      clearInterval(this.countdownInterval)
    }
  },
  mounted() {
    window.addEventListener('beforeunload', this.stopCountdown)
  },
  unmounted() {
    window.removeEventListener('beforeunload', this.stopCountdown)
  }
}
</script>

위 예시에서 mounted 훅에서 window 객체의 beforeunload 이벤트에 대한 리스너를 등록하고, unmounted 훅에서 해당 리스너를 제거합니다. 이렇게 함으로써 컴포넌트가 삭제될 때 이벤트 리스너도 함께 제거되므로 메모리 누수가 발생하지 않습니다.

 

 

(2) v-cloak 디렉티브의 사용

 

Vue 애플리케이션이 초기화되는 동안 렌더링 지연이 발생할 수 있습니다.

이 때 v-cloak 디렉티브를 사용하면 초기화되기 전에는 화면에 나타나지 않도록 할 수 있습니다.

예시 코드:

<template>
  <div v-cloak>
    {{ message }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, world!'
    }
  }
}
</script>

<style>
[v-cloak] {
  display: none;
}
</style>

 

이 외에도 위에서 언급한 v-if와 v-show의 적절한 사용, watch와 computed 속성의 적절한 사용, v-for를 사용할 때 key 속성 사용 등도메모리 최적화와 성능을 높이는데 도움을 줍니다.

 

 

 

반응형