javascript - 页面上许多视频的 Internet Explorer 和 Edge 中的视频、内存管理问题导致它们显示为暗色/黑色和/或无法播放
问题描述
我们有一个包含 77 个左右视频缩略图的页面。将鼠标悬停在视频缩略图上时,视频开始在缩略图空间内播放。
在它们中的许多(8 到 60 个,取决于系统/浏览器)悬停后会出现问题。视频开始播放不正确或不播放。基本上,平坦/冗余区域全部变暗。在 Edge 中,这会在一两秒后自行纠正,但对于我们的客户来说,这是非常不受欢迎的行为。
我们通过调用pause()
、删除src
属性,然后调用load()
具有空src
属性的元素来暂停每个视频,如下所示:
function pauseVideo(e) {
$('video', this).get(0).pause();
$('video', this).get(0).removeAttribute('src');
$('video', this).get(0).load();
}
这清除了一些内存,但问题仍然存在,尽管在问题变得明显之前可以播放更多视频。
我似乎确实与内存有关,并暴露了在我们看来是 Microsoft 浏览器中的内存泄漏。每个视频都会增加内存使用量,而且内存永远不会被清除,就像在 Chrome 和 Firefox 中一样。当任务管理器中的内存使用量接近 600mb 到 1gb(取决于系统)时,通常会出现此问题。(Chrome 总是大约 500-550 兆字节。Firefox 大约 700-800 兆字节。)
我们注意到行为何时开始发生取决于视频卡的一些差异,但问题总是在某个时候出现。
所有这些视频都显示在页面的多个位置。所以我想知道的一件事是是否可以在元素之间共享视频内存。
还有一些其他问题可能相关。在 IE 中,视频完全变黑,并且它们的尺寸在屏幕上发生变化,从而可以改变页面布局。
这是一个相关的问题,但它不是重复的,因为它没有提供关于必须在一页上促进 80 个左右的视频的问题或解决方案:How to proper unload/destroy a VIDEO element
我们正在 IE 版本 11.228.17134.0 和 Edge 版本 42.17134.1.0 上进行测试,这两个版本都是当前最新的。
最初所需的功能是当用户将鼠标悬停在视频上时视频在帧上暂停,但现在看来,如果我们必须卸载视频,我们将无法做到这一点。
当它可用时,我将全天添加有关此问题的更多信息。
解决方案
我们的团队有一个脚本可以检测 DOM 元素是否在页面的可视区域内,是否滚动到顶部上方或底部下方。当用户滚动时,脚本添加/删除一个类,并为每个添加了行为的元素调度自定义事件。我能够利用这个系统来暂停、删除和处理(垃圾收集)不在视图中的视频元素,然后在它们返回视图时重新填充它们,并将原始属性存储在与关联的对象数组中每个视频/缩略图。
这将处理视频。该函数必须用 调用.call()
,例如:disposeVideo.call(videoElement)
;
var disposeVideo = function () {
this.pause();
delete(this);
$(this).remove();
}
奇怪的是,虽然这delete(this)
是一个 hack,并且不应该在任何浏览器中工作,但它似乎在所有浏览器中工作,根据我读过的关于这个问题的评论,以及我在 IE/Edge 中的发现。
在 IE(不是 Edge)上,这会降低页面滚动速度。这是由于我们对页面上的 80 个项目进行了视图检查,或者与重新下载海报(缩略图)和视频有关,因为它似乎没有有效地将这些资产缓存到立即(重新)可用于渲染器。
与上述相关的另一个副作用(也在 IE 中)是,当您滚动视频时,视频会显示为空白,直到重新下载资产。我们选择使用分层在视频后面的图像,以支持对被删除的视频元素使用海报属性。这样,屏幕上永远不会出现空白视频缩略图。
更新:屏幕上有两个或更多视频元素可能会导致问题。我们只展示了一个(100% 有效),但没有尝试确定可能的最大视频元素数量。
推荐阅读
- sql - oracle,从表或数据库模式级别设置时区
- tizen - Tizen 工作室未能构建秒表模板
- sockets - 找不到类型“ServerSocketConnectEvent”
- mysql - 一般意义上的h2与hibernate和MySql之间的区别
- php - TYPO3 流体阵列访问
- laravel - 从 Laravel 的数据库中获取 email_verified 检查条件数据
- ios - React-Native:错误:无法为 iOS 项目安装 CocoaPods 依赖项,这是此模板所需的
- android - 帆布?或 View.onDraw() 方法中的 Canvas
- mysql - “字段列表”中的未知列“u.MemberId”
- algorithm - 随机森林的可能算法