前端 BUG 录 - audio 意外的 pending 挂起状态


思否
前端BUG录 调试 Vue

转载自 SegmentFault

最近公司一直在做众审平台相关的功能,大多数还都和音视频有关,前端终究还是逃不过这一劫。

疯狂遇到 BUG, 今天来说说其中一个:audio 加载时意外的长时间 Pending 问题。

BUG 场景

  • vue 框架
  • 移动端(android 和 ios 的兼容也挺坑,尤其是低版本)
  • 偶现(测试数据很难复现)
  • 资源是 cdn,存在海外节点。(意味着不是海外用户访问慢)

BUG 原因猜测

  • cdn 回源慢,报错快。未监听报错。 因为测试环境数据很难复现。线上数据比较新,怀疑是首次使用回源导致。 但是经过排查并不是,因为线上数据推到了第二天,还是存在问题。 而且也监听了报错事件。

访问达到限制,导致后续请求挂起。 首先我们都知道 chrome 同一域名并行加载资源的数量是 6 个。那么我们来尝试复现一下这个问题。 (的确可以复现)

// 设置一个计数器,可以用控制台的过滤功能看日志。
// count = 0;
// tag = `${Date.now()}-${Math.random()}-count${count++}`
tag = `${Date.now()}-${Math.random()}`

// 初始化一个 audio 标签
audio = new Audio()
// 设置资源地址
audio.src= "http://chuangshicdn.file.m.mvbox.cn/upload/1cfd8d964385aeb8d3b3051396146314_927674570_1.m4a?" + tag

// 获取 audio 所有事件,触发事件就打日志
audioEventList = [];
for(var i in audio) /^on/.test(i) && audioEventList.push(i)
audioEventList.forEach(v=>{
    audio[v] = console.log.bind(console, v, tag)
})

// 可以尝试播放音频,这样播放完毕之后会继续加载。
// audio.play()

那么基于这个测试,我就有理由怀疑,vue 异常的更新了节点,导致 audio 被阻塞。 类似于 .lazy 异常状态的 input。 https://www.lilnong.top/static/html/bug-vue-audio-pending-status.html 但是又没有成功复现,淦。

问题总结

问题复现不稳定,所以只能盲猜。目前来看是修复了,方案用的是 reload

解决方案

  • 刷新页面 location.reload(),基于我们上面定位的问题,我们可以刷新页面来规避资源阻塞的问题。
  • 因为默认的 audio 标签是会自动中止资源加载的。所以我们可以把 audio 标签移出 Vue 环境。
  • 资源加载超时时,提示用户刷新页面。
  • ajax 加载资源,然后做控制。但是需要跨域支持,而且加载也比较慢。为了好的体验还得上 AudioContext 有点太复杂了。

微信公众号:前端linong

欢迎大家关注我的公众号。有疑问也可以加我的微信前端交流群。


原文:SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。