首页 > 解决方案 > 可能的内存泄漏 - Javascript Watchers,用于动画数据的动态 CSS 变量

问题描述

背景:我正在使用在内部 Linux 服务器板上运行的 Vue.js 和 Typescript 来托管一个 UI,该 UI 使用网络上的引擎数据动态更新。当我们接收到引擎数据(如 RPM 值)时,我们会更新 SVG 转换来为仪表设置动画。

问题:在仪表视图的 .vue 路由上,应用程序在大约一个小时后变得无响应,并且这只发生在这个特定的视图上。大约一个小时后,用户界面锁定,但在我后台应用程序并返回后它恢复正常功能。当 UI 停止更新时,我也无法再单击任何按钮或与 vue UI 中的任何内容进行交互。

这是一些(简化的)代码来解释这个 .vue 文件中的事情是如何工作的

HTML:在完整代码中,我有大约 16 个不同的 svg 对象,我通过 Javascript 更新 CSS stroke-dashoffset 属性来制作动画

<template>
   <div>
      <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 761.27 456.243">
         <g id="Animate">
            <g class="gauges-48">
               <line id="fuelAnimate" clip-path="url(#clip-path)" class="gauges-49" x1="37.14" y1="168.353" x2="37.14" y2="80.413"/>
            </g>
         </g>
      </svg>
   </div>
</template>

<style scoped>
#fuelAnimate{
--offset: 87;          
stroke-dasharray: 90;
stroke-dashoffset: var(--offset);;
transition: stroke-dashoffset 0.3s;
}

</style>

在我的 JS 代码中,当页面加载时,我获取我的 DOM 引用,根据 this.$store.state.boat.fuelLevel 的当前值计算偏移量,并设置属性

我有一个@Watcher,它在 store.ts 更新fuelLevel 值时执行操作:


<script lang="ts">
import {Component, Prop, Vue, Watch} from 'vue-property-decorator';

@Component
export default class Gauges extends Vue {

   fuel_Level: any;      // Stores reference to the DOM object
   fuelOffset: any = 87  // Value we use to set the new stroke-dashoffset

  constructor(){
    super();
  }

  mounted(){
    setTimeout(() => {
      this.computeOffset()
    }, 50);  
  }

 //Runs once, as the page is loaded
 computeOffset() {
   // I have 16 set functions, once for each gauge in the view
   this.setFuel()

   setTimeout(this.updateLevels, 250);
 }

  updateLevels(){
    // In full code, I have 16 getElementById's
    this.fuel_Level = document.getElementById('fuelAnimate')

    // And 16 setProperty's, to set the initial offset values
    if(this.fuel_Level) 
      this.fuel_Level.style.setProperty('--offset', this.fuelOffset.toString());  
  }

  setFuel(){
    //I thought my problem could be with updating global vars, nulling the values didn't help
    this.fuelOffset = null 
    this.fuelOffset = 89 - ((this.$store.state.boat.fuelLevel) * (87/100));
  }

  // Whenever this.$store.state.boat.fuelLevel is updated via Store.ts, perform these actions
  @Watch('$store.state.boat.fuelLevel')
    onFuelChanged(value: string, oldValue: string){
      // Updates and assigns new value to this.fuelOffset based on Engine Data value
      this.setFuel() 
  
      // Sets the new offset, to animate gauge and reflect current data 
      if(this.fuel_Level) 
        this.fuel_Level.style.setProperty('--offset', this.fuelOffset .toString());  
  }
}
</script>
  

我真的很感谢这里的任何输入,也许我忽略了一些东西,但我无法弄清楚为什么我所做的任何事情都会导致 UI 锁定。如果有人需要尝试帮助我,我可以提供完整的代码。

标签: javascripttypescriptvue.jsmemory-managementmemory-leaks

解决方案


推荐阅读