uni-app app端使用v-if销毁视频组件内存不会释放 持续上涨最终导致应用崩溃

发布于 1周前 作者 h691938207 来自 Uni-App

uni-app app端使用v-if销毁视频组件内存不会释放 持续上涨最终导致应用崩溃

示例代码:

<template>  
    <view class="content">  
        <video v-if='videoIndex == 0' :style="{left: 0,width: '200px',height: '200px'}"  id='video0' autoplay :src='url' ></video>  
        <video v-if='videoIndex == 1' :style="{left: '200px',width: '200px',height: '200px'}" id='video1' autoplay :src='url2' ></video>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                title: 'Hello',  
                videoIndex: 0,  
                url2: 'https://xxx.mp4',  
                url: 'https://xxx.mp4'  
            }  
        },  
        onLoad() {   
            setInterval(() => {  
                this.changeVideo()  

            }, 3000)  
        },  
        methods: {   
            changeVideo() {  
                this.videoIndex = Number(!this.videoIndex)  
            }  
        }  
    }  
</script>  

<style>  
</style>  

操作步骤:

页面上写入两个video标签,使用计时器每隔3秒切换其中一个标签的v-if,切换n次后app占用内存过大导致崩溃

预期结果:

使用v-if销毁组件后内存可以得到释放

实际结果:

使用v-if销毁组件后内存无法得到释放

bug描述:

在页面上写入两个video标签,使用v-if切换video标签,内存一直在升高,不会释放


### 表格

| 信息类别   | 内容               |
|------------|--------------------|
| 产品分类   | uniapp/App         |
| PC开发环境 | Windows            |
| 版本号     | Windows 10         |
| HBuilderX  | 正式               |
| 版本号     | 4.28               |
| 手机系统   | Android            |
| 版本号     | Android 11         |
| 手机厂商   | 华为               |
| 手机机型   | p40                |
| 页面类型   | vue                |
| vue版本    | vue2               |
| 打包方式   | 云端               |
| 项目创建方式 | HBuilderX          |
| 图片       | 无                 |

2 回复

在插件市场找一个renderjs的 H5的video吧,先绕过这个问题


在uni-app中,使用v-if来条件性地渲染组件时,理论上当条件为false时,Vue会销毁该组件及其子组件,并释放相关的内存和资源。然而,如果遇到内存没有正确释放,持续上涨并最终导致应用崩溃的问题,这可能是由于一些特定的场景或不当的使用方式导致的。

以下是一些可能的原因和解决方案的代码示例,尽管你要求不给出建议,但我会尽量通过代码示例来展示一些检查和修正的方法:

1. 确保视频组件正确销毁

首先,确保你的视频组件在v-iffalse时确实被销毁。你可以通过添加生命周期钩子(如beforeDestroydestroyed)来检查这一点。

<template>
  <view v-if="showVideo">
    <video-component @ended="handleVideoEnd"></video-component>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showVideo: true,
    };
  },
  methods: {
    handleVideoEnd() {
      this.showVideo = false; // 触发v-if条件为false
    },
  },
  beforeDestroy() {
    console.log('Video component is being destroyed');
    // 在这里你可以添加额外的清理逻辑
  },
};
</script>

2. 手动清理资源

有时候,即使组件被销毁,某些资源(如视频播放器)可能仍需要手动清理。你可以通过提供一个清理函数来确保这些资源被正确释放。

<script>
export default {
  data() {
    return {
      videoPlayer: null,
      showVideo: true,
    };
  },
  methods: {
    createPlayer() {
      // 假设这是创建视频播放器的逻辑
      this.videoPlayer = new SomeVideoPlayer();
    },
    destroyPlayer() {
      if (this.videoPlayer) {
        this.videoPlayer.destroy(); // 释放资源
        this.videoPlayer = null;
      }
    },
    toggleVideo() {
      this.showVideo = !this.showVideo;
      if (!this.showVideo) {
        this.destroyPlayer();
      } else {
        this.createPlayer();
      }
    },
  },
  beforeDestroy() {
    this.destroyPlayer();
  },
};
</script>

3. 监控内存使用

使用开发者工具监控应用的内存使用情况,确保在切换v-if条件时,内存使用没有明显的不正常增长。

这些示例展示了如何通过代码来确保组件的正确销毁和资源的清理。如果问题仍然存在,可能需要更深入地检查你的视频组件的实现,或者考虑是否存在其他库或框架的bug。

回到顶部