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
中使用 nview
的 video
组件时,如果列表中的视频数量超过 300 个,真机可能会崩溃。这通常是由于内存占用过高或渲染性能问题导致的。以下是一些可能的解决方案:
1. 分页加载
- 实现思路:不要一次性加载所有视频,而是采用分页加载的方式,每次只加载当前页面的视频数据。
- 实现方法:使用
scroll-view
或onReachBottom
事件监听滚动到底部时加载下一页数据。 - 优点:减少一次性加载的数据量,降低内存占用。
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. 懒加载
- 实现思路:只加载当前可见区域的视频,其他视频在滚动到可见区域时再加载。
- 实现方法:使用
IntersectionObserver
或uni.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-app
的scroll-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. 使用原生组件
- 实现思路:如果
nview
的video
组件性能不足,可以考虑使用原生组件(如video
标签)或原生插件。 - 实现方法:使用
uni-app
的原生插件或自定义原生组件。 - 优点:原生组件通常性能更好,适合处理大量视频。
6. 内存管理
- 实现思路:手动管理内存,及时销毁不再使用的视频组件。
- 实现方法:在视频离开可视区域时,销毁视频组件或释放资源。
- 优点:减少内存占用,避免内存泄漏。
methods: {
destroyVideo(index) {
this.$set(this.videoList[index], 'loaded', false);
}
}