메모이제이션을 통한 Vue.js 성능 개선

10150 단어 vuewebdevjavascript
몇 주 전에 메모이제이션을 통해 Vue.js 애플리케이션의 성능 문제를 해결할 수 있었습니다. 결과는 "매개 변수가 있는 Vue.js 계산 속성"처럼 보이지만 불가능합니다!

문제



문제는 이 큰 타임라인 구성 요소에 나타났습니다.



짧게 만들려면:
  • 1줄 = 한 사람을 위한 1주일의 이벤트;
  • 이벤트가 겹칠 수 있습니다(Bob은 월요일 아침에 이벤트가 있음).

  • 그리드(left, width, top, height/lineHeight)에 이벤트를 배치하려면 이 이벤트가 다른 이벤트와 겹치는지 계산하는 함수를 호출해야 합니다. 이 함수는 여러 번 호출되었으며 때로는 동일한 매개변수로 호출되었습니다.

    이 구성 요소는 내 로컬 환경™️에서 잘 작동하는 데 사용되었습니다.

    그러나 더 많은 이벤트/일(≃ 더 많은 사각형)과 더 많은 사용자(≃ 더 많은 행)로 인해 이야기가 달라졌습니다. 구성 요소가 표시되는 데 ~4 ~ ~6초가 걸렸습니다. console.count()를 추가했는데 내 함수가 +700번 호출되었음을 깨달았습니다! 🙈

    첫 번째 호출은 computed() 캐시된 속성(반응 종속성을 기반으로 함)을 사용하는 것이었습니다. 불행히도 그들은 매개변수로 작동하지 않습니다. 즉, 다음과 같이 할 수 없습니다.

    export default {
      data: () => ({
        events: [/* ... */]
      }),
      computed: {
        // ❌ NOT WORKING!
        eventPosition(event) {
          // ...
        }
      }
    }
    
    


    나는 다른 것을 찾아야만 했다.

    구출을 위한 메모이제이션!



    (메모이제이션이 무엇인지 이미 알고 있다면 다음 부분으로 바로 건너뛸 수 있습니다)

    메모이제이션은 함수형 프로그래밍 개념입니다. 아이디어는 함수의 내부 캐시를 사용하여 매개변수를 저장하는 것입니다. 함수가 처음 호출되면 값을 계산한 다음 출력을 캐시에 저장합니다. 이 함수가 동일한 매개변수로 두 번째로 호출되면 캐시에서 값을 반환합니다.

    피보나치 함수는 이 구현이 재귀를 사용하기 때문에 메모화가 작동하는 방식의 좋은 예입니다. 이 예에서 함수는 동일한 인수를 사용하여 여러 번 호출할 수 있습니다.

    // without memoization
    function fibonacci(n) {
      return (n <= 1) ? 1 : fibonacci(n - 1) + fibonacci(n - 2)
    }
    


    메모이제이션을 사용하면 동일한 기능이 다음과 같이 작성됩니다.

    // with memoization
    function fibonacci(n) {
      // 1
      if (typeof fibonacci.cache === 'undefined') {
        fibonacci.cache = []
      }
    
      // 2
      if (!fibonacci.cache[n]) {
        fibonacci.cache[n] = (n <= 1) ? 1 : fibonacci(n - 1) + fibonacci(n - 2)
      }
    
      // 3
      return fibonacci.cache[n]
    }
    
    


    이 기능을 3단계로 나누었습니다.
  • 함수가 처음 실행될 때 빈 캐시를 정의합니다.
  • 계산하려는 값이 캐시에 없으면 계산하여 캐시에 추가합니다.
  • 캐시된 값을 반환합니다.

  • 두 번째 console.count(n)if()를 추가하면 메모이제이션으로 fibonacci(12)fibonacci(4)의 값을 34가 아닌 한 번만 계산하는 것을 볼 수 있습니다!

    🧐 어떻게 그게 가능해?



    메모이제이션은 JavaScript에서 함수가 Object의 프로토타입이기 때문에 가능합니다.

    const myCoolFunction = () => true
    typeof myCoolFunction. __proto__ // "function"
    typeof myCoolFunction. __proto__. __proto__ // "object"
    
    


    보시다시피 메모이제이션을 사용하면 코드의 가독성을 성능과 맞바꿉니다.

    Vue.js의 메모이제이션



    이제 메모이제이션이 어떻게 작동하는지 살펴봤습니다. 이 기술을 Vue.js 구성 요소에 적용하는 방법을 살펴보겠습니다. 이를 위해 함수를 Vue의 methods에 넣어야 합니다. 그러면 이전에 본 것과 거의 동일합니다.

    // MyComponent.vue
    export default {
      data: () => ({
        events: [/* ... */]
      }),
      methods: {
        positionEvent(event) {
          if (typeof this.positionEvent.cache === 'undefined') {
            this.positionEvent.cache = []
          }
    
          if (!this.positionEvent.cache[event.id]) {
            const somethingToCache = heavyFunction(event)
            // 🔼 add your function here
            this.positionEvent.cache[event.id] = somethingToCache
          }
    
          return this.positionEvent.cache[event.id]
        }
      }
    }
    
    


    💡 팁:
  • 메서드 이름 앞에 this를 추가하는 것을 잊지 마십시오.
  • 필요에 따라 캐시 키를 자유롭게 조정하십시오!

  • 그만한 가치가 있습니까?



    이 특별한 경우에 그렇습니다. 내 구성 요소가 동일한 매개 변수로 시간이 많이 걸리는 기능을 여러 번 사용하고 있습니다.

    구성요소 렌더링이 ~4초에서 ~0.3초로 단축되었습니다. 10배 빠르다!!



    그러나 메모이제이션을 golden hammer 으로 보지 않습니다. 솔직히 말해서 몇 년 동안 웹 개발하면서 메모이제이션을 사용한 것은 처음입니다.


    오늘은 여기까지입니다!

    이 기사를 읽어 주셔서 감사합니다 🤘. 도움이 되었기를 바랍니다. 마음에 드셨다면 ❤️ 또는 🦄를 눌러주세요!

    당신도 할 수 있습니다 💙


    maxpou.fr에 원래 게시되었습니다.

    좋은 웹페이지 즐겨찾기