作者 | 作业帮技术团队
编辑 | 闫园园
背景介绍
作业帮的直播间以信令为基本做教师端,学生端的同步渲染。全部直播间包含推拉流,流媒介渲染,聊天区,课件区,连麦, 通用互动等功能,其中课件区包含 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 框架优化,在上一部分内容播放器优化里有介绍。
总结 黑白屏降至千分位;
追查问题有效;
繁杂度降低,迭代成本降低;
单一内容问题,不影响后续播放。
作者介绍:
张士标,作业帮直播课堂前端团队负责人,致力于课件、互动系统的连续性能优化和探索。
|