如何解决Svelte条件渲染视频与图片切换时的加载空白卡顿问题
问题根源
现有逻辑仅以videoSrc是否存在作为渲染判断条件:GraphQL返回视频地址后会立刻销毁占位图、挂载Video组件,但此时视频资源还处于网络加载阶段,组件还未渲染出可展示的画面,直接导致1-3秒的空白屏。
修复方案
新增独立的视频就绪状态标记,只有「视频地址已获取」+「视频资源加载完成可立即播放」两个条件同时满足时,才隐藏占位图。
第一步:新增状态与事件逻辑
在组件script标签中添加如下代码:
<script> export let videoSrc; export let imageSrc; // 视频是否加载完成可展示,默认未就绪 let videoReady = false; // 视频地址更新时,重置就绪状态 $: if (videoSrc) { videoReady = false; } // 视频可播放时触发,标记为就绪 function handleVideoReady() { videoReady = true; } // 视频加载失败时保持占位图展示,避免永久空白 function handleVideoLoadError() { videoReady = false; } </script>
第二步:调整模板渲染逻辑
不要在拿到视频地址时就立刻销毁占位图,提前挂载Video组件触发资源加载,等视频就绪后再隐藏占位图:
<div class="media-container"> <!-- 拿到视频地址后立刻挂载组件,提前触发资源加载 --> {#if videoSrc} <Video src={videoSrc} on:canplay={handleVideoReady} on:error={handleVideoLoadError} class="media-content" class:media-hidden={!videoReady} /> {/if} <!-- 视频未就绪时始终展示占位图,覆盖在视频上层 --> {#if !videoSrc || !videoReady} <img src={imageSrc} alt={imageSrc} class="media-content media-placeholder" /> {/if} </div> <style> .media-container { position: relative; width: 100%; /* 按你的视频实际比例设置,避免布局偏移 */ aspect-ratio: 16/9; } .media-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } .media-hidden { /* 未就绪的视频隐藏在下层,不影响占位图展示 */ z-index: 0; } .media-placeholder { z-index: 1; } </style>
注意事项
- 如果你使用的是自定义封装的
Video组件,需要在组件内部把原生<video>标签的canplay、error事件向外透传,父组件才能正常监听到加载状态,透传方式就是在原生video标签上添加on:canplay、on:error即可,Svelte会自动把事件冒泡到父组件。 - 如果你的视频需要自动播放,可将监听事件从
canplay替换为loadeddata,该事件触发时视频第一帧已经完成解码,切换时不会出现黑屏。 - 务必给容器设置固定宽高比,避免图片和视频切换时引发布局偏移。
内容的提问来源于stack exchange,提问作者lache
相关产品推荐
相关产品推荐

