学习
实践
活动
工具
TVP
写文章

作业帮直播间前端架构优化实践

背景介绍

作业帮的直播间以信令为基础做教师端,学生端的同步渲染。整个直播间包括推拉流,流媒体渲染,聊天区,课件区,连麦, 通用互动等功能,其中课件区包括 H5 课件、Cocos 课件、白板、互动题、小游戏等。整体课件区内容的呈现是在 Webview 里,Webview 运行时聚合了多个不同种类的内容。下图为作业帮直播间功能简图。

技术难点

  • 终端碎片化带来多种内容渲染的稳定性;
  • 直播间性能保证,整体内存 /CPU 控制,子功能模块内存 /CPU 分配;
  • 信令到达保证及各个环节的有序执行;
  • 容错,任一内容环节出问题,如何保证不影响后续运行;
  • 不同技术栈内容的持续性接入。

现状

前面介绍了整个直播间多背景知识以及前端的一些技术挑战,前端的主要功能区在课件区,可以看下优化之前的老架构,对整体有个粗略的认识。

所有的业务层代码聚合在称之为 zb 的模块,从图中可以粗略看出 zb 模块是一个比较庞大的模块,承载了众多不同技术体系的内容渲染和调度,也是反馈问题的重灾区,运行在一个常驻的浏览器之上。

随着用户规模的不断增大,不同的用户机型设备的增多以及内容的丰富度和效果的提升,我们的 zb 稳定性以及性能遇到了很大的挑战,线上的工单反馈也有上升趋势。来自用户侧反馈的问题大概为以下几类:

  • 课件区黑屏,白屏,花屏;
  • 卡在某一个具体的页面,中断了同步;
  • 卡顿;
  • 互动题做不了;
  • 看不到老师笔记。

问题分析

通过大量的测试以及问题排查列举出我们的架构存在以下问题:

  • Webview 内存占用持续上升,无法及时 GC,内存不足是导致黑白屏的根本原因,Webview 的回收机制对我们来说是黑盒,尤其是基于 DOM 方式的渲染,研发无法通过代码触发 GC;
  • 卡顿的原因来源于一些动画造成 CPU, 内存瞬间增长;
  • 信令全链路到达有丢失,服务 -> NA -> Webview ,NA -> Webview 通信没有机制保障,兜底保证通信代码较多,即使信令到达,执行的时机以及完成时机都有一定程度业务的耦合;
  • 渲染不同内容的调度逻辑耦合较多业务逻辑,逻辑链路较深,排查问题较难;
  • 任一内容的逻辑出错或者报错有可能影响后续信令处理和调度逻辑;
  • 统一运行在同一个 Webview,不同内容的消耗很难通过指标进行量化;
  • 课件区内部分层不清晰,耦合较重;
  • 排查问题与不同角色的技术,边界不清晰,沟通成本高,排查效率低。

设计目标

根据直播间的面临的技术难点以及结合我们目前架构所面临的问题,我们希望新架构能够实现以下几个目标:

  • 底层保证内存及时回收;
  • 底层渲染 Runtime 可切换;
  • 通信可靠性保证(NA/FE);
  • 内容隔离;
  • 调度逻辑与不同内容解藕;
  • 单个内容针对性降低内存 /CPU 并且可量化

实践 & 探索

作业帮直播间的前端架构

容器及 SDK 设计

容器设计

容器的定义

容器是直播间任何内容的载体,容器可以是 Native 容器,里面运行着 Native 的组件,可以是一个 Webview 容器,可以是一个 Cocos 容器。容器有以下几个特点:

  • 载体;
  • 独立无依赖;
  • 生命周期;
  • 独立开发,独立部署。

有了容器之后,我们可以把调度逻辑独立出来,下沉到端,这一层可以更专注任务的调度以及信令的处理,与内容解耦。

容器的状态

容器 SDK 设计

有了容器的抽象,各个内容如何集成到容器内以及如何感知容器的不同的状态切换,需要一个标准 SDK 去帮助封装所有的底层细节,对业务无感。SDK 需要具备以下能力:

  • 生命周期钩子;
  • 支持自定义调试;
  • 支持后续的扩展;
  • 基础工具库。

可以通过下面这张图,简单了解 SDK 的容器周期和实现逻辑:

内容播放器

有了容器以及调度,作为内容的业务开发,可以更专注于某一个内容本身,为了保证后续内容的可持续规范性接入,我们针对不同的内容做了一层抽象,定义为内容播放器。我们的主要播放器有 H5 PPT 播放器,H5 互动题播放器,Cocos 课件及互动播放器,画版播放器等,下面会重点介绍下 H5 PPT 播放器以及详细介绍下 Cocos 播放器架构层面的一些优化方案。

H5 PPT 播放器

这里我们以 H5 PPT 为例来介绍基于新架构播放器的分层,H5 PPT 是由编辑器生产出一份数据 + 资源去驱动内容及动画的展示,参考下图,自底往上分别为: 

1. 容器层,负责播放器运行时;

2. 前端的基础库; 

3. 适配层, 播放器纯渲染层和直播间的适配,包括容器生命周期的桥接,信令的注册与处理 ;

4. 播放器的渲染层。

Cocos 内容播放器设计与优化

Cocos 内容播放器是比较复杂的一个播放器,代码量非常庞大,接下来会重点介绍下我们针对 Cocos 播放器结合新架构做的一系列优化。

当前问题

  • 信令恢复不稳定容易出问题;
  • 加载和恢复性能差,耗时久;
  • 线上问题排查困难,不易锁定。

问题分析

  • 依赖过程的同步同步逻辑,如果出现信令丢失或者信令顺序错误,则会造成逻辑错误,并且后续的所有操作和渲染逻辑都会受到影响;
  • 每次加载 Cocos 引擎、Framework、互动内容都会消耗大量的加载时间,同时依赖过程的恢复逻辑类似于帧同步,决定了断线恢复的时候要恢复之前的所有逻辑,耗时较长,CPU 占用较高;
  • 同步逻辑是同步的 Touch 事件派发,所以数据中的事件表示不出业务逻辑,只有客户端响应后才知道触发了何种逻辑。

解决方案及技术难点

  • 重构信令恢复机制,改为状态同步,状态同步可以解决数据错乱和丢包造成的结果不正确问题,以及恢复时耗时的性能问题,同时排查线上问题也能有明确数据内容来锁定问题。但状态同步有两个问题需要解决:与业务解耦和同步的数据量;
  • 加载性能和内存问题,一个通过采用 Runtime 提前初始化,另一个采用生产时对内容进行标准化限制。

状态同步设计

设计思路:底层捕获输入事件以及渲染数据变化,避免业务感知同步逻辑,状态数据的同步与业务逻辑解耦,降低研发成本,同时增加增量状态和全量状态两种数据,来解决数据量大的问题。

下面这张图是节点状态变化的捕获和分发流程,这个机制在多个端之间也可以正常运作,比如从 A 端捕获的状态派发给 B 端,这就满足的主讲的操作可以同步到学生端的诉求。

下面是状态数据量的优化策略,虽然全部数据已经通过上面的逻辑控制的比较低了,但是为了更高效,并不是每帧都同步全部数据,是在关键帧把数据同步,其它帧只同步增量,这样既保证了数据量也保证了准确性,即使有丢失错乱,但是在下次全量数据是也一定能够恢复正确状态。

内存和 cpu 优化

上一部分容器的抽象,容器可以被调度,可以被销毁,在一定程度可以保证渲染内容的及时回收,接下来这部分针对不同内容做的一些优化手段。内存 /CPU 优化在我们场景中有很多的优化动作,包括客户端独立进程,Cocos 方向等,下面的环节重点介绍基于 Webview 运行时的内容的优化。

浏览器渲染过程

上面是浏览器渲染相关比较核心的一张图,如果你深入理解了浏览器整个渲染流程,就很清楚浏览器会在哪些阶段会有 CPU 以及内存的消耗,我们可以大概列举如下:

  • JS 代码复杂度及运行频率,会导致 CPU 消耗,操作 DOM 也会消耗内存;
  • JS 代码内存泄漏;
  • DOM 会被解析 LayoutObject,所以复杂大量的 DOM 嵌套,会导致 CPU 和内存的消耗;
  • CSS 同样会被解析 Object,复杂的 CSS 规则会导致 CPU,CSS 规则也可能导致 GPU 内存的消耗;
  • 图片资源,解码 CPU 消耗,渲染是高内存消耗;
  • 回流、重绘会导致 CPU 内存增长;
  • 巧用合成层会减少 GPU 内存消耗,要避免层爆炸。

图片渲染过程

  • IO;
  • 解码(CPU 解码,位图 -> GPU);
  • 渲染管线 (顶点计算 / 光栅化 / 片元着色 / 帧缓冲渲染到屏幕)。

图片内存

  • 位深 (color depth (32 /24 …)。
  • 尺寸 (图片分辨率)。
  • 体积 (磁盘存储所需大小)。

图片占用显存的计算方式如下:

width * height * (colorDepth/8) /(1024 * 1024)= X (M)

1024 * 1024 * (32/8)/(1024 * 1024) = 4M

可以看出图片尺寸对于内存的影响较大。

优化手段

  • 图片压缩 / 图片裁剪;
  • GIF 抽帧,GIF 按照 12fps 抽帧;
  • 动画降帧,Lottie 按照设计帧率运行,并降低至 12fps;
  • 互动题题版,运行时按需加载;
  • GIF 作为合成层渲染,GPU 降低较明显;
  • 信令发送频率及数据量降低;
  • 白板相关优化涉及内容较多,不在这里阐述;
  • Cocos 框架优化,在上一部分内容播放器优化里有介绍。

 总结

  • 黑白屏降至千分位;
  • 追查问题高效;
  • 复杂度降低,迭代成本降低;
  • 单一内容问题,不影响后续播放。

作者介绍:

张士标,作帮直播课堂前端团队负责人,致力于课件、互动系统的持续性能优化和探索。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/Rr7U1xRZ3OvpC7Mtz9Yu
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券