基于Video.js的Swiper背景视频幻灯片页面卡顿优化请求
优化Swiper背景视频在老旧设备上的性能问题
你的问题核心在于当前代码会让非活跃幻灯片的视频也保持播放状态——特别是slideChangeTransitionEnd事件里同时启动了prev和next幻灯片的视频播放,这会导致老旧设备上多个视频同时解码渲染,占用大量CPU/GPU资源,直接引发卡顿。下面是针对性的优化方案:
核心优化思路
- 仅保持当前活跃幻灯片的视频处于播放状态
- 切换幻灯片时,立即暂停并重置非活跃幻灯片的视频(释放资源)
- 避免重复绑定事件(原代码的
toggleMute在每次切换时都绑定新事件,会导致事件堆积)
修改后的完整JS代码
/* home page */ $(window).load(function() { var swiper = new Swiper('.swiper-container', { direction: 'vertical', slidesPerView: 1, spaceBetween: -1, mousewheel: true, preventClicks: true, allowTouchMove: true, preventClicksPropagation: true }); // 统一管理所有Video.js实例,避免重复创建 var videoPlayers = {}; $('.swiper-slide video').each(function() { var videoId = $(this).attr('id'); videoPlayers[videoId] = videojs(videoId, { muted: true, playsinline: true, loop: true, autoplay: false // 仅在幻灯片激活时再播放,避免初始加载就全部启动 }); }); // 切换幻灯片时更新头部样式 swiper.on('slideChange', function() { $("#header").toggleClass("active", swiper.realIndex !== 0); }); // 下一张幻灯片点击事件 $(".scrolldown").on("click", function (e) { e.preventDefault(); swiper.slideNext(); return false; }); // 自适应幻灯片高度 function setSlideHeight() { $(".swiper-slide, .swiper-container").height($(window).height()); } setSlideHeight(); $(window).resize(setSlideHeight); // 静音/播放控制逻辑(仅绑定一次,避免事件堆积) function setupVideoControls() { // 点击播放按钮取消静音并播放 $(document).on("click", ".swiper-slide-active .play_video", function (e) { e.preventDefault(); var activeVideoId = $(".swiper-slide-active video").attr("id"); var player = videoPlayers[activeVideoId]; if (!player) return; $(".content").removeClass("delay"); $("body").addClass("music_on"); player.currentTime(0); player.play(); player.muted(false); player.one("ended", function () { $("body").removeClass("music_on"); player.muted(true); setTimeout(function () { $(".content").addClass("delay"); }, 1000); }); }); // 点击静音按钮/幻灯片其他区域静音 $(document).on("click", ".swiper-slide-active .cross_video, .swiper-slide-active:not(.play_video)", function (e) { if ($(e.target).hasClass('play_video')) return; var activeVideoId = $(".swiper-slide-active video").attr("id"); var player = videoPlayers[activeVideoId]; if (!player) return; player.muted(true); $("body").removeClass("music_on"); setTimeout(function () { $(".content").addClass("delay"); }, 1000); }); // ESC键全局静音 $(document).keyup(function (e) { if (e.keyCode === 27 && $(".swiper-slide-active video").length) { var activeVideoId = $(".swiper-slide-active video").attr("id"); var player = videoPlayers[activeVideoId]; player.muted(true); $("body").removeClass("music_on"); setTimeout(function () { $(".content").addClass("delay"); }, 1000); } }); } setupVideoControls(); // 幻灯片切换时更新视频状态的核心函数 function updateVideoOnSlideChange() { // 暂停所有非活跃幻灯片的视频并重置到开头,释放资源 $('.swiper-slide:not(.swiper-slide-active) video').each(function() { var videoId = $(this).attr('id'); var player = videoPlayers[videoId]; if (player && !player.paused()) { player.pause(); player.currentTime(0); } }); // 播放当前活跃幻灯片的视频(保持静音) if ($(".swiper-slide-active video").length) { var activeVideoId = $(".swiper-slide-active video").attr("id"); var player = videoPlayers[activeVideoId]; if (player) { player.muted(true); player.play(); } } } // 初始加载时激活第一个幻灯片的视频 updateVideoOnSlideChange(); // 幻灯片切换开始时立即更新视频状态 swiper.on("slideChangeTransitionStart", function () { $("body").removeClass("music_on"); updateVideoOnSlideChange(); }); });
关键优化点解释
统一管理Video.js实例
提前初始化所有视频实例并存储在videoPlayers对象中,避免每次切换时重复调用videojs()创建新实例,减少不必要的资源消耗。仅播放当前活跃视频
新增updateVideoOnSlideChange函数,在幻灯片切换时自动暂停非活跃视频并重置播放位置,只启动当前活跃幻灯片的视频,从根源上减少同时运行的视频数量。避免事件堆积
原代码每次切换幻灯片都会重新绑定控制事件,导致同一元素绑定多个重复事件。现在改为一次性事件委托绑定,既支持动态元素,又避免了事件堆积问题。禁用初始自动播放
移除HTML中视频的autoplay属性,改为仅在幻灯片激活时通过JS控制播放,避免页面加载阶段所有视频同时启动。
额外的老旧设备优化建议
- 给视频添加
preload="metadata",仅预加载视频元数据而非完整视频,减少初始加载压力 - 提供多分辨率视频源,通过
<source>标签的media属性让低性能设备自动加载低分辨率版本 - 可以通过
window.performanceAPI检测设备性能,在低性能设备上自动替换视频为静态图片背景
内容的提问来源于stack exchange,提问作者z-1881
相关产品推荐
相关产品推荐

