【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

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

  • 2022-06-22
  • 本文字数:3266 字

    阅读完需:约 11 分钟

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

背景介绍


作业帮的直播间以信令为基础做教师端,学生端的同步渲染。整个直播间包括推拉流,流媒体渲染,聊天区,课件区,连麦, 通用互动等功能,其中课件区包括 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 框架优化,在上一部分内容播放器优化里有介绍。

 总结


  • 黑白屏降至千分位;

  • 追查问题高效;

  • 复杂度降低,迭代成本降低;

  • 单一内容问题,不影响后续播放。


作者介绍:


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

2022-06-22 11:502818

评论

发布
暂无评论
发现更多内容

Zookeeper配置详解

Regan Yue

zookeeper 配置 10月月更

绝绝子!美团大牛吐血整理总结“消息队列核心知识笔记”是真的吊

进击的王小二

分布式 MQ 消息队列 java

微博评论高性能高可用计算架构

Imaginary

架构实战营 设计微博系统中”微博评论“的高性能高可用计算架构

💤 ZZzz💤

架构实战营

从Android系统架构学习设计模式

轻口味

android 架构设计原则 10月月更

服务业CRM软件能为你提供哪些服务?

低代码小观

企业管理 CRM 管理系统 管理工具 管理软件

重学 Java 之 5种字符流读取方法

进击的王小二

java基础 字符流 java

构建全屏 Web 应用程序

devpoint

JavaScript html5 大前端 10月月更

用区块链技术打造AEO高信用国际贸易生态圈的创新实践

CECBC

健身房CRM软件帮你寻找更多客户

低代码小观

企业管理 管理系统 健身房 管理软件 行业

一口气面试7家大厂,已拿下4家offer,其实大厂没有你想象中难!

程序员小呆

Java 程序员 面试 架构师 资料

反序列化漏洞复现总结

网络安全学海

黑客 网络安全 信息安全 WEB安全 安全漏洞

模块5作业

4anonymous

微博评论高性能高可用架构设计

Geek_db27b5

面对疾风吧,如何搭建高协同的精准告警体系?

阿里巴巴云原生

阿里云 产品 云原生 Arms 告警运维中心 告警体系

极客时间【架构实战营】第二期 模块五作业

Geek_91606e

架构实战营

NFT商业落地中的思考:区块链

CECBC

如何说孩子才肯听,怎么听孩子才肯说(上)

石云升

读书笔记 育儿 10月月更

5G通话占道4G,你的5G套餐性价比真的高吗?

脑极体

创建线程池学习笔记

风翱

线程池 10月月更

模块五作业

potti

架构实战营

Webrtc Rtp/rtcp (2)

webrtc developer

WebRTC rtp/rtcp

实时监控:基于流计算 Oceanus ( Flink ) 实现系统和应用级实时监控

腾讯云大数据

流计算 Oceanus

模块五-微博评论的高性能高可用计算架构

娜酱

「架构实战营」

“区块链+物联网”融合 推动产业创新发展

CECBC

声网教育aPaaS 产品灵动课堂:「低代码」开发,15分钟极速上线

声网

人工智能 大数据 云服务

山东移动用明道云赋能一线,打通业务创新最后一公里

明道云

WeTest自助压测1折起,最低1分钱参与Q币抽奖

WeTest

自定义View:几何变换实质与技巧

Changing Lin

10月月更

阿里开源的这个库,让 Excel 导出不再复杂(既要能写,还要写的好看)

看山

Java EasyExcel 10月月更

架构实战营第五次作业

Geek_d18264

架构实战营

作业帮直播间前端架构优化实践_大前端_作业帮技术团队_InfoQ精选文章