如何优化淘宝直播 PC 推流端性能(下)

简介: 如何优化淘宝直播 PC 推流端性能(下)

如何优化淘宝直播 PC 推流端性能(上):https://developer.aliyun.com/article/1480499


如何监控淘宝直播 PC 推流端性能


上文提到的只是应用里众多性能问题的几个 case,然后基于本地性能工具进行 case by case 分析优化。那我们是不是可以把性能监控起来,主动发现运行时性能问题并制定一些降级策略呢?


首先我们要明确哪些是应用关心的性能指标,比如淘宝直播 PC 推流端主要看重如下几个性能指标:

前端性能指标

  1. 页面帧率及卡顿率
  2. NAPI 及长任务耗时

客户端性能指标

  1. CPU
  2. GPU
  3. 单帧耗时
  4. 画面帧率
  5. 内存

其次我们应该如何采集这些性能数据呢?


 采集性能数据


  • 前端性能指标


页面帧率及卡顿率


我们知道 chrome performance 工具的 Rendering 面板里把 FPS meter 选项勾选上之后,就可以统计出页面帧率。



那从代码层面要如何获取呢?其实可以通过 requestAnimationFrame API 来统计一段时间内的页面帧率(如一秒内有多少帧,就是我们常见的 fps),实现代码如下:

const detectPageFPS = () => {
  let lastFameTime = performance.now()
  const loop = () => {
    const curFrameTime = performance.now()
    // 统计每一帧耗时
    const fpsTime = curFrameTime - lastFameTime
    lastFameTime = curFrameTime
    window.requestAnimationFrame(loop)
  }
  loop()
}


然后我们参考业界定义卡顿的标准,当帧与帧之间间隔超过 200 ms 时就认为一次卡顿。最后就可以通过卡顿时间总和 / 总时长得出页面卡顿率。


NAPI 及长任务耗时


首先我们先来了解下 NAPI 是 Node.js 官方提供的一个用来编写 C/C++ 插件的稳定模块,而在淘宝直播 PC 推流端中,推流页面里(如场景元素操作)都是通过 NAPI 接口调用 C++ 的 obs、race、artc 等模块,目前有 200 个 NAPI 接口。



那我们要怎么统计这么多 NAPI 接口耗时呢?Chrome 提供了一个专门用于性能监控的 web API:PerformanceObserver。PerformanceObserver 主要用于监测性能度量事件,在浏览器的性能时间轴记录新的 performanceEntry 时会以回调的方式通知 observer,通过 PerformanceObserver 我们就可以用代码的方式拿到用户本地真实的性能耗时数据了。


首先在每个 NAPI 接口前后标记 mark,并注册 measure 事件:

performance.mark(`${NAPI} startTime`)
// NAPI 接口调用
performance.mark(`${NAPI} endTime`)
performance.measure(`[PerformanceMeasureSdk]${NAPI}`, `${NAPI} startTime`, `${NAPI} endTime`)


然后监听 measure 事件,就可以获取到所有已经标记的 NAPI 接口耗时了:

const performanceObserver = new PerformanceObserver(async (list, _obj) => {
    const perfEntries = list.getEntries()
    for (let i = 0; i < perfEntries.length; i++) {
      const p = perfEntries[i]
      logger.info(`[Performance]performanceObserver ${p.entryType}`, p.duration)
    }
})
performanceObserver.observe({ type: 'measure', buffered: true })


至于长任务耗时,之前是从 chrome performance 面板录制获取(如下图所示),我们也可以通过上文提到的 PerformanceObserver API 来实现。在介绍如何捕获卡顿之前需要先搞明白一个概念,究竟什么是长任务?长任务是指长时间(大于等于 50ms)独占主线程,导致界面卡顿的 JavaScript 代码,比如以下常规场景:

  1. 长耗时的事件回调
  2. 代价高昂的回流和其他重绘
  3. 浏览器在超过 50 毫秒的事件循环的相邻循环之间所做的任务


介绍完长任务后,我们可以通过以下代码来获取:

let profiler = new (window as any).Profiler({ sampleInterval: 10, maxBufferSize: 10000 })
const performanceObserver = new PerformanceObserver(async (list, _obj) => {
    const perfEntries = list.getEntries()
    for (let i = 0; i < perfEntries.length; i++) {
      const p = perfEntries[i]
      const trace = await profiler.stop()
      logger.info('[Performance]performanceObserver longtask', trace)
      // 重新开始记录
      profiler = new (window as any).Profiler({ sampleInterval: 10, maxBufferSize: 10000 })
    }
})
performanceObserver.observe({ type: 'longtask', buffered: true })


在此基础上,我们还可以在触发长任务事件时,使用 js-self-profiling API 把 js 堆栈也一起 dump 下来分析。但因安全问题浏览器默认是不开启的,需要通过拦截请求添加 Document-Policy: js-profiling 响应头来实现:

// 拦截请求,添加 Document-Policy: js-profiling 响应头
win.webContents.session.webRequest.onHeadersReceived(
  {
    urls: ['*://*/*'],
  },
  (details: Electron.OnHeadersReceivedListenerDetails, callback: any) => {
    if (details.responseHeaders) {
      details.responseHeaders['Document-Policy'] = ['js-profiling']
    }
    callback({ cancel: false, responseHeaders: details.responseHeaders })
  },
)

最终就可以采集到长任务耗时并抓取 js 堆栈了:


在此基础上,我们还可以利用 PerformanceObserver API 监听 resource 来收集网络请求的信息,也可以监听用户触发的 click 事件来获取用户触发的 DOM 元素,结合前面的 js 堆栈综合分析长任务耗时的性能问题。


  • 客户端性能指标


目前应用内的 CPU、GPU、单帧耗时、画面帧率、内存等性能指标都是通过 SDK 获取的,获取方式也比较简单,就不再赘述。

 上报性能数据进行算力管控


上文已经介绍了前端、客户端性能指标是如何采集的,接下来就会每隔 10 秒用 UT 接口汇总上报这些性能数据到 Medialab 平台进行监控。


同时,我们也实现了一套算力管控策略。当开始推流时,编码器检测到每 2 分钟内编码帧率 < 15 fps(720p)、18 fps (1080p)(可配置) 时,回调算力状态及原因给前端,进行算力管控(所有管控策略都支持动态配置,包括管控等级和顺序、管控指标、管控项等):

  1. 第一级:当前应用 CPU < 30% 时,检查是否存在高消耗外部应用,提示用户手动关闭占用高的外部应用
  2. 第二级:低采集帧率提示,检测到当前摄像头设备帧率过低时给与提示
  3. 第三级:切硬编
  4. 第四级:降帧率(720p 最低 20 fps,1080p 最低 25 fps,自动降级不提示),并自动关闭端智能、纯净流、礼物特效播放等功能
  5. 第五级:开启了美妆、AI磨皮等高功耗功能时,提示用户手动关闭这些功能
  6. 第六级:降分辨率(toast 提示用户已降级,已有功能)


经过算力管控优化后,我们大盘推流卡顿率降低了很多。  


总结及展望

 总结

基于线上用户反馈的性能问题,我们运用本地性能工具优化了启动耗时(应用启动耗时从 10s -> 2.5s,推流页面启动耗时从 5s -> 50 ms)、运行时性能优化(包括前端页面交互耗时优化、客户端性能优化),并提出可以把性能指标(包括页面帧率及卡顿率、NAPI 及长任务耗时、CPU、单帧耗时等)监控起来主动发现运行时性能问题并制定一些降级策略。


 展望


接下来还可以做的事情是继续优化应用的 NAPI 及长任务耗时,优化应用 CPU、单帧耗时等性能指标,针对应用性能风险提示可以分系统、应用、功能模块进行降级处理。


团队介绍


我们是淘天业务技术淘宝直播B端终端团队,负责淘系增长非常快的直播业务,业务上升空间非常大。在技术方面,我们在探索直播间互动、游戏互动、数据可视化、音视频播放器、微前端、智能搭建、Web 3D、Electron跨端开发、桌面推流客户端开发、跨 PC/H5/Native 的多端架构等。在这里你有机会通过一行代码为业务创造亿级 GMV 增量,期待优秀的你!

目录
相关文章
|
21天前
|
缓存 前端开发 JavaScript
如何优化淘宝直播 PC 推流端性能(上)
如何优化淘宝直播 PC 推流端性能(上)
35 2
|
2月前
|
监控 NoSQL Java
记一次线上商城系统高并发的优化
记一次线上商城系统高并发的优化
16 0
|
5月前
|
编解码 监控 定位技术
抖音技术分享:抖音Android端手机功耗问题的全面分析和详细优化实践
本文结合抖音的功耗优化实践中产出了一些实验结论,优化思路,从功耗的基础知识,功耗组成,功耗分析,功耗优化等几个方面,对 Android 应用的功耗优化做一个总结沉淀。
217 0
|
10月前
|
定位技术 CDN
开源直播源码平台处理卡顿问题技巧方案
开源直播源码加速器功能就成功实现了,加速器功能有助于提高直播平台的竞争力,并满足用户对高质量、稳定和流畅的直播体验的需求,这也让加速器功能成为开源直播源码平台的重要功能之一。
开源直播源码平台处理卡顿问题技巧方案
|
存储 缓存 固态存储
PC体验天花板如何突破?
英特尔670p SSD,将重塑硬盘市场格局。 近日,英特尔面向消费级市场正式推出基于144层QLC技术的670p固态硬盘,这款硬盘曾在去年的“2020英特尔内存存储日”活动上亮相,主要用来满足大容量、高性能、高性价比及耐用性等用户需求。 英特尔670p SSD包括512GB、1TB、2TB三种容量版本,适用于桌面、笔记本的日常计算、办公、内容创作、主流游戏等场景,同时也是轻薄型笔记本电脑的存储方案选择。目前,英特尔670p SSD已经可在网络零售商处单独购买,而联想、戴尔、惠普等厂商也会在4月份发售采用此款固态硬盘的PC产品,届时将会掀起一股新的QLC固态硬盘潮流。
PC体验天花板如何突破?
|
存储 机器学习/深度学习 算法
优酷移动端组件智能测试方案
随着优酷APP上内容运营方案和玩法的丰富,针对分发和消费业务场景,内容配置平台上的运营组件数量也在增多,移动端的回归测试工作量激增。如何跟随业务发展的脚步,又保证组件测试质量的高效率?本文将分享优酷在该方面的思考和探索
286 0
优酷移动端组件智能测试方案
|
Web App开发 设计模式 缓存
新工具开源!一款双11养猫5亿用户的互动引擎(附地址)
阿里巴巴历时2年自研开发的互动游戏引擎Eva.js正式开源,致力于让前端工程师更低成本的开发互动游戏,并已经在淘宝、天猫、支付宝、优酷、考拉、菜鸟、盒马等业务场景中使用。
新工具开源!一款双11养猫5亿用户的互动引擎(附地址)
|
机器学习/深度学习 编解码 缓存
成本更低、更优观看体验——自研S265编解码器解析
带宽是直播运营中最大的成本,根据前瞻网估算全行业2020年的CDN费用支出将超过300亿元,在2025年接近1000亿规模(https://bg.qianzhan.com/trends/detail/506/200715-ec767b9b.html),可以说降低带宽是成本控制中至关重要的一环。
成本更低、更优观看体验——自研S265编解码器解析
|
监控 黑灰产治理
直播平台开发干货分享——标准直播及快、慢直播的特性
 所谓自己做直播平台开发,要结合不同的应用场景,相对应的功能、硬件、软件配套技术也不同。根据应用场景的不同,自建直播平台可以分为标准直播、快直播和慢直播。本文将简单地为大家分析一下这三点的特性。
直播平台开发干货分享——标准直播及快、慢直播的特性
|
视频直播
直播系统的开发中怎么样做才会更好的引流
你也知道流量在这个时代就是代表着钱,可你却不知道如何引流,直播系统已成为现在当之无愧的流量平台大户,想要从这里面“搞点”收益,那你就得好好看看这篇文章,兴许你与成功就差这一点。
直播系统的开发中怎么样做才会更好的引流