uni-app nview video列表超过300个后真机会崩溃 知道怎么解决吗

uni-app nview video列表超过300个后真机会崩溃 知道怎么解决吗

开发环境 版本号 项目创建方式
Mac 11.6.5 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Mac

PC开发环境操作系统版本号:11.6.5

HBuilderX类型:正式

HBuilderX版本号:3.3.13

手机系统:iOS

手机系统版本号:iOS 15

手机厂商:苹果

手机机型:iphone8

页面类型:nvue

vue版本:vue2

打包方式:云端

项目创建方式:HBuilderX

### 示例代码:

```html
<template>  
    <view>  
        <list @loadmore="loadMore">  
            <cell class="item" v-for="(item, index) in list" :key="item.id">  
                <video class="video"></video>  
                <text>hello world</text>  
            </cell>  
            <cell class="loading-more">  
                <div style="height: 80rpx;">  
                    <loading-indicator class="loading-icon" animating="true"></loading-indicator>  
                </div>  
            </cell>  
        </list>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                page:1,  
                list:[],  
            };  
        },  
        onLoad() {  
            for(let i=0;i<50;i++) {  
                this.list.push({  
                    id:"r"+i  
                })  
            }  
        },  
        methods:{  
            loadMore(){  
                this.page++  
                console.log(this.page)  
                setTimeout(()=>{  
                    for(let i=0;i<50;i++) {  
                        this.list.push({  
                            id:"r"+i  
                        })  
                    }  
                },1000)  
            }  
        }  
    }  
</script>  

<style lang="scss">  
.item{  
    .video{  
        width: 760rpx;  
    }  
}  
</style>  

操作步骤:

下拉10页左右就会崩溃

预期结果:

崩溃

实际结果:

崩溃

bug描述:

项目需求做一个video的下拉列表,试了下iphone8和iphone12pro,估计真机都这样,分页每页20个,估计刷到15页左右,就会闪退。


更多关于uni-app nview video列表超过300个后真机会崩溃 知道怎么解决吗的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

可以试一下 recycle-list 复用的list 先试一下
https://uniapp.dcloud.net.cn/component/recycle-list.html

更多关于uni-app nview video列表超过300个后真机会崩溃 知道怎么解决吗的实战教程也可以访问 https://www.itying.com/category-93-b0.html


uni-app 中使用 nviewvideo 组件时,如果列表中的视频数量超过 300 个,真机可能会崩溃。这通常是由于内存占用过高或渲染性能问题导致的。以下是一些可能的解决方案:

1. 分页加载

  • 实现思路:不要一次性加载所有视频,而是采用分页加载的方式,每次只加载当前页面的视频数据。
  • 实现方法:使用 scroll-viewonReachBottom 事件监听滚动到底部时加载下一页数据。
  • 优点:减少一次性加载的数据量,降低内存占用。
data() {
  return {
    videoList: [],
    page: 1,
    pageSize: 20
  };
},
methods: {
  loadMore() {
    // 模拟加载下一页数据
    const newVideos = this.getVideos(this.page, this.pageSize);
    this.videoList = this.videoList.concat(newVideos);
    this.page++;
  },
  getVideos(page, pageSize) {
    // 模拟获取视频数据
    return Array.from({ length: pageSize }, (_, i) => ({
      id: (page - 1) * pageSize + i,
      src: `https://example.com/video${i}.mp4`
    }));
  }
},
onReachBottom() {
  this.loadMore();
}

2. 懒加载

  • 实现思路:只加载当前可见区域的视频,其他视频在滚动到可见区域时再加载。
  • 实现方法:使用 IntersectionObserveruni.createIntersectionObserver 监听视频元素是否进入可视区域。
  • 优点:进一步减少内存占用,提升性能。
data() {
  return {
    videoList: Array.from({ length: 300 }, (_, i) => ({
      id: i,
      src: `https://example.com/video${i}.mp4`,
      loaded: false
    }))
  };
},
onReady() {
  this.videoList.forEach((video, index) => {
    const observer = uni.createIntersectionObserver(this);
    observer.relativeToViewport().observe(`#video-${index}`, (res) => {
      if (res.intersectionRatio > 0) {
        this.$set(this.videoList[index], 'loaded', true);
        observer.disconnect();
      }
    });
  });
}

3. 虚拟列表

  • 实现思路:只渲染当前可见区域的视频项,其他视频项在滚动时动态渲染。
  • 实现方法:使用 uni-appscroll-view 或第三方虚拟列表组件(如 vue-virtual-scroll-list)。
  • 优点:大幅减少渲染的 DOM 元素数量,提升性能。
<template>
  <scroll-view scroll-y style="height: 100vh;" @scroll="handleScroll">
    <view v-for="(video, index) in visibleVideos" :key="video.id" :id="`video-${index}`">
      <video :src="video.src" v-if="video.loaded"></video>
    </view>
  </scroll-view>
</template>

<script>
export default {
  data() {
    return {
      videoList: Array.from({ length: 300 }, (_, i) => ({
        id: i,
        src: `https://example.com/video${i}.mp4`,
        loaded: false
      })),
      startIndex: 0,
      endIndex: 20
    };
  },
  computed: {
    visibleVideos() {
      return this.videoList.slice(this.startIndex, this.endIndex);
    }
  },
  methods: {
    handleScroll(event) {
      const scrollTop = event.detail.scrollTop;
      const itemHeight = 100; // 假设每个视频项高度为 100px
      this.startIndex = Math.floor(scrollTop / itemHeight);
      this.endIndex = this.startIndex + 20;
      this.loadVisibleVideos();
    },
    loadVisibleVideos() {
      this.visibleVideos.forEach(video => {
        if (!video.loaded) {
          this.$set(video, 'loaded', true);
        }
      });
    }
  }
};
</script>

4. 优化视频资源

  • 实现思路:减少视频资源的大小和质量,降低内存占用。
  • 实现方法:压缩视频文件,使用更低的码率或分辨率。
  • 优点:减少内存占用,提升加载速度。

5. 使用原生组件

  • 实现思路:如果 nviewvideo 组件性能不足,可以考虑使用原生组件(如 video 标签)或原生插件。
  • 实现方法:使用 uni-app 的原生插件或自定义原生组件。
  • 优点:原生组件通常性能更好,适合处理大量视频。

6. 内存管理

  • 实现思路:手动管理内存,及时销毁不再使用的视频组件。
  • 实现方法:在视频离开可视区域时,销毁视频组件或释放资源。
  • 优点:减少内存占用,避免内存泄漏。
methods: {
  destroyVideo(index) {
    this.$set(this.videoList[index], 'loaded', false);
  }
}
回到顶部