uni-app 在nvue页面中 list组件内放置video list有固定高度 上拉加载视频时卡住闪退
uni-app 在nvue页面中 list组件内放置video list有固定高度 上拉加载视频时卡住闪退
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | 6.1 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
PC开发环境操作系统版本号:6.1
HBuilderX类型:正式
HBuilderX版本号:3.2.9
手机系统:Android
手机系统版本号:Android 10
手机厂商:华为
手机机型:pot-al00a
页面类型:nvue
打包方式:云端
项目创建方式:HBuilderX
### 示例代码:
```html
<list v-if="!isKong" [@loadmore](/user/loadmore)="loadmore" class="video-list" :show-scrollbar="false" :style="{height:height}">
<cell ref="items" style="width:750rpx;" v-for="(item,index) in list" :key="item.id">
<view class="video-list-cell" :style="{'padding-top':index==0?'30rpx':''}">
<view class="video-box">
<view class="video_c">
<video
@pause="pauses(index)"
@ended="pauses(index)"
:id="'video'+index"
:src="item.videoSrc" controls class="video"
v-if="!item.isZB||item.isPlay">
</video>
</view>
<view class="img-box" @click="plays(index)" v-if="!item.isPlay">
<image :src="item.img" mode="" class="poster"></image>
<image src="../../static/index/play.png" mode="" class="play"></image>
</view>
</view>
<view class="txt" @click="goToDetail(item)">
<text class="txt-c">{{item.title}}</text>
</view>
<view class="v_bottom">
<text class="name">{{item.source}}</text>
<text class="time name">{{item.date}}</text>
</view>
</view>
</cell>
<cell v-if="list.length>0"><uni-load-more :status="more"></uni-load-more></cell>
<!-- <loading></loading> -->
</list>
操作步骤:
在nvue页面中,list组件中,放置是video list有固定高度,上拉加载视频时,卡住闪退。加载几次还可以,但是加载多了就卡住闪退。
预期结果:
更Vue页面一样,可以滚动长列表不卡顿闪退。
实际结果:
在nvue页面中,list组件中,放置是video list有固定高度,上拉加载视频时,卡住闪退。加载几次还可以,但是加载多了就卡住闪退。
bug描述:
在nvue页面中,list组件中,放置是video list有固定高度,上拉加载视频时,卡住闪退。加载几次还可以,但是加载多了就卡住闪退。 控制台出现: draw android view, exception:WX_RENDER_ERR_LAYER_OVERFLOWLayer overflow limit error: 24 layers! 卡住闪退是由video组件引起的。
更多关于uni-app 在nvue页面中 list组件内放置video list有固定高度 上拉加载视频时卡住闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你是仿抖音效果吗?如果不是可以使用recycle-list https://uniapp.dcloud.io/component/recycle-list
更多关于uni-app 在nvue页面中 list组件内放置video list有固定高度 上拉加载视频时卡住闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html
<cell-slot> 包含自定义组件时,在 Android 上有性能问题,我的包含自定义组件,还是不行
回复 1***@qq.com: 你可以先试下 看下效果
这个问题是典型的 nvue 中 video 组件在长列表中的性能瓶颈。WX_RENDER_ERR_LAYER_OVERFLOW 错误表明超出了原生渲染的层级限制(默认24层),每个 video 组件都会创建复杂的原生渲染层,在 list 中快速累积导致崩溃。
核心解决方案是优化 video 组件的渲染和管理:
-
使用
recycle-list替代list(强烈推荐)recycle-list是nvue专为超长列表设计的组件,通过严格的单元格复用机制大幅减少内存占用。将list标签直接替换为recycle-list,cell替换为cell-slot。这是解决此类问题最根本的方法。 -
实现视频组件的懒渲染与销毁 在滚动列表中,同时存在多个
video实例是主因。需要监听滚动,仅让可视区域内的1-2个视频处于真实渲染和播放状态。- 计算可视区域: 利用
list或recycle-list的[@scroll](/user/scroll)事件,结合boundingClientRect异步API,判断哪些cell处于屏幕内。 - 条件渲染
video: 在cell的模板中,增加一个数据项(如isInViewport)。只有isInViewport为true时,才渲染真正的video组件。否则,仅展示封面图(poster)。上拉加载新数据时,新加入的video默认应处于未渲染状态。 - 销毁非活跃视频: 当
cell滑出可视区域时,不仅要切换为封面图,最好能通过v-if彻底销毁video组件实例,释放原生资源。
- 计算可视区域: 利用
-
优化
video组件属性- 确保所有
video标签都设置了正确的poster(封面图)属性。这能在视频未播放时展示静态图,减少资源占用。 - 非活跃视频应确保处于
paused状态。你已有的@pause和@ended事件处理是好的,需要确保滑出视口的视频能触发暂停。
- 确保所有
-
检查并限制列表项高度 你已设置
list有固定高度:style="{height:height}",这很好。请确保每个cell的高度也是大致固定或可计算的,这有助于recycle-list进行高效回收。避免cell内存在高度动态变化极大的内容。 -
分页加载策略 虽然你已有上拉加载,但建议设置一个最大列表项数量上限(例如100条)。加载更多时,可以移除最早期的部分项(如移除前20条),而不是无限累积。这在内容流场景中是常见做法,能从根本上控制内存增长。
代码调整方向示例(基于 recycle-list 和懒渲染思路):
<recycle-list v-if="!isKong" [@loadmore](/user/loadmore)="loadmore" class="video-list" :show-scrollbar="false" :style="{height:height}" [@scroll](/user/scroll)="handleScroll">
<cell-slot v-for="(item,index) in list" :key="item.id">
<view class="video-list-cell">
<view class="video-box">
<!-- 关键:根据计算出的 isInViewport 条件渲染 video -->
<view class="video_c" v-if="item.isInViewport && (!item.isZB || item.isPlay)">
<video
@pause="pauses(index)"
@ended="pauses(index)"
:id="'video'+index"
:src="item.videoSrc"
controls
class="video"
:poster="item.img" <!-- 确保设置封面 -->
></video>
</view>
<!-- 非可视区域或未播放时,只显示封面图 -->
<view class="img-box" v-else @click="plays(index)">
<image :src="item.img" mode="" class="poster"></image>
<image src="../../static/index/play.png" mode="" class="play"></image>
</view>
</view>
<!-- ... 其他文本内容 ... -->
</view>
</cell-slot>
<cell v-if="list.length>0"><uni-load-more :status="more"></uni-load-more></cell>
</recycle-list>

