奇巴布Feed流性能优化

news/2024/12/31 6:11:57/

01

   项目背景

d4019623db2452a7219d093769cbdf72.png

“爱奇艺奇巴布”是爱奇艺为0-8岁孩子和家长定制化设计的寓教于乐平台,为儿童量身打造精致的观看体验,精彩内容解锁寓教于乐新方式。为儿童提供优质动画内容的同时,我们更关注APP用户体验。在产品交互设计上我们立足儿童视角,把内容浏览和观影做到做到简约易用。奇巴布APP整体界面简约、导航清晰、播放流畅,以极致的设计理念荣获2018年德国红点传达设计奖。

在技术侧我们不断完善技术架构体系,优化提升APP各项性能指标,发挥工匠精神把APP的用户体验做到极致。优化技术方向包括:APP冷启动、Crash防控、内存管理、电量消耗、安装包体积等。奇巴布APP历经数年迭代开发,产品功能不断完善,叠加儿童移动设备换新频次相对成人低,奇巴布APP首页Feed流在老旧设备滑动使用过程中会出现卡顿情况,滑动中有视频播放等场景时页面卡顿比较明显,影响用户体验。

02

   问题现状


  • 卡顿原因

屏幕刷新率由硬件决定,通常是 60Hz/S,或者由 OS 和硬件协调动态调整刷新率。当程序通过 CPU、GPU 渲染画面的过程中,耗时超过一次刷新间隔,就会使得屏幕画面没有更新,导致卡顿现象产生,影响用户体验。

  • Feed卡顿问题分析

使用性能较差的手机滑动Feed流,通过Xcode-Instruments工具分析在滑动过程中具体耗时分布情况。截取代表性性能分析图,如下:

00da64297c1039a2dd8465368141b88e.pngHitch 出现时的耗时调用堆栈1db53eed5abf87b648b0f511d621f20b.png

滑动列表时的统计曝光耗时堆栈

Feed卡顿问题分析总结如下:

  1. Feed中存在较多不同样式Card,多种Card类的合计初始化耗时较长;

  2. Feed中有各种图片,这些本地图片资源在主线程读取和渲染,有性能提升空间;

  3. Feed滑动中图片库(基于SDWebImage二次开发)在读取磁盘缓存文件过程中耗时较长,且在主线程中做读取操作;

  4. Feed滑动过程中播放器开播与停播耗时较长;

  5. Feed滑动过程中Card区块曝光引发频繁Pingback投递,整体耗时较长。

03

   解决方案


  • Card数据解析与渲染异步处理

使用QoS的NSQualityOfServiceUserInitiated创建自定义队列,当前设备CPU活跃核心数和自定义最大核心数比较,获得结果设置队列上限。通过限制并发数量减少多个线程频繁切换带来CPU资源损耗,避免GCD API频繁创建线程。Card数据解析和布局计算、播放器内核初始化、图片和文本渲染都使用该自定义队列来处理。

  • 首页Card预加载

在奇巴布Feed列表中前几屏幕业务数据大多为固定推荐内容组合,Card类型繁多无法复用,因此预先加载前几屏不同Card实例是提高性能的一种技术手段。具体解决方案如下:

  1. 预加载策略:

    APP每次冷启动时,总体策略是以最快速度展示内容给用户,缩短启动时间。首页Feed接口在发送网络请求过程中有网络延迟,在服务端数据传送到本地之前加载本地磁盘缓存的上次启动时Feed流JSON数据。利用磁盘中持久化的JSON数据,解析出JSON对应的Card类,将常用的Card类名缓存到内存,以备在合适的时机初始化Card实例,以备后续滑动Feed时直接读取Card实例,从而避免在滑动过程中初始化。

  2. 预加载时机的判别与执行:

在用户启动APP的瞬间,会存在大量异步业务操作抢占CPU资源。所以需要寻找CPU闲置且用户没有手势操作时预加载Card。监测与执行大体实现逻辑是:通过向主线程RunLoop添加Observer监听DefaultMode,监听作用的时间点为线程进入休眠之前或RunLoop即将退出。当方法回调触发时,意味着用户没有滑动或者滑动结束,在回调方法中做预加载。

  • 本地图片预解码

46eaa1458f046e5ce0c76373d9730bbf.pngFeed中各种本地图片

Feed中不同类型Card中的角标和占位图,这些图片为本地资源,在用户滑动Feed时,过往实现方式是在主线程中从磁盘读取资源,然后进行渲染。将这些I/O操作放入子线程,在图标使用前提前生成Bitmap到内存中,可以减少用户在滑动过程中因加载图片带来的性能损耗。具体解决方案如下:

  1. 预加载策略:

    在APP首页渲染完成后,异步执行统计常用Card中依赖的角标和占位图,提前生成Bitmap, 并加载到内存。Hook图片调用方法[UIImage imageNamed:],在后续调用[UIImage imageNamed:] 方法时将省去I/O和解码过程,并通过以图片名键值匹配方式存储避免多次缓存。

  2. 解码方案:

强制解码过程:iOS15.0以上系统直接调用系统方法imageByPreparingForDisplay进行预解码,其他系统版本则使用 CGBitmapContext 强制解码。

  • 图片库读取优化

图片库设置组件的图片策略是通过异步下载URL对应图片并做缓存。本次优化主要是针对已经加载到缓存的图片,当对应Card再次滑入屏幕时,第一时间加载缓存中图片而不是再走图片库内部方法各种业务逻辑判断。

  • 其他优化

  1. 针对问题现状中第4个问题:Feed滑动过程中播放器开播与停播耗时较长,解决办法是在滑动时避免播放器的初始化,避免播放器的停播,维持播放状态与滑动前一致。另外在Card停播时显性的调用停止加载数据API,防止播放器在后台异步加载数据。

  2. 针对问题现状中第5个问题:Card区块曝光引发频繁Pingback投递耗时较长,且在主线程中操作。解决思路是滑动时对统计方法限流、降低调用频次。曝光精度会有非常小的下降,但在可接受范围内。

04

   项目总结


  • 技术总结

以UML时序图汇总优化技术点,如下图:

42c86c2b8a7815791ddf7a23ead6ca1a.png

  • 项目收益

使用Apple Xcode工具Scroll Hitch Rate监测优化效果,优化后每秒滑动挂起降低至1.4ms,远低于Apple对滑动流畅的标准5ms/s,即使在性能较差的低端机上滑动也非常流畅,用户体验有较大提升。

aee79f2726b52ab9cd36c1c4044a8179.png

注:Scroll Hitch Rate表示图像帧延迟显示在屏幕上的时间总和 Hitch time除以用户滑动屏幕的持续时间 Scroll duration 得到一个比例,它可以反映用户感受到的滑动卡顿的严重程度。

6261be8d72181d7ec9681c3121543f8e.jpeg

也许你还想看

Prometheus监控指标查询性能调优

爱奇艺DRM修炼之路

组件化设计在会员业务的应用和实践


http://www.ppmy.cn/news/93502.html

相关文章

21 VueComponent 事件的处理

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 测试用例 测试用例如下, 一个简单的 按钮事件的触发 问题的调试 调用…

c# CAD二次开发 模拟CAD移动图形, 通过圆现在注记,改变图形颜色

c# CAD二次开发 模拟CAD移动图形, 通过圆现在注记,改变图形颜色 using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Colle…

矿井水除氟——高矿化度矿井水氟化物深度降解的技术方案

高矿化度矿井水是指含有高浓度溶解性矿物质的废水,通常指的是含有高浓度钠、钙、镁、铁、铝、钾等离子的废水。这些离子通常来自于废水所处的环境、工业或生产过程中使用的原材料和化学品。高矿化度的废水通常具有高盐度、高电导率、高硬度等特征,对环境…

梦笔记0527

早晨醒得早,玩了一会手机又睡着了。 梦里又回到了泰山信息科技的门口,想再看看那个灯光照耀下的橙色文字。大门象是用胶带贴住了,灯没开,黑乎乎的。使劲摇了几下,整个墙好像是木板,晃动着。 突然意识到解散…

堆的实现+堆的应用(堆排序和Topk)

珍惜当下的一切,相信未来的一切都是美好的。 -- 丹尼尔迪凯托目录 一.堆的概念及结构 二.堆的各种函数的实现 1.结构体的内容 2.堆的初始化 3.堆的插入 4.堆的向上调整法 5.验证堆的向上调整法 6.堆顶的删除 7.堆的向下调整法 8.返回堆…

收藏这些素材网站,不再担心没有剪辑素材

不想真人出镜拍摄视频素材的小伙伴们,还在为没有剪辑素材而担心? 今天这期内容大周来把自己压箱底的素材网站分享给粉丝们,抓紧点赞收藏! 1、footage123 来自全世界各国的素材资源这里都有,以高清的航拍视频为主 2…

python实现神经网络之---构建神经元模型1(python3.7)

本文主要要以周志华的机器学习书为蓝本编写 第5章神经网络 5.1python 实现神经元模型 神经网络中最基本的成分是神经元 (neuro且)模型,如下图所示: 1943 年, [McCulloch and Pitts, 1943] 将上述情形抽象为国 5.1所示的简单模型&#xff0c…

数据结构初阶--栈和队列OJ题

目录 前言有效的括号思路分析代码实现 用队列实现栈思路分析代码实现 用栈实现队列思路分析代码实现 设计循环队列思路分析代码实现 前言 本篇文章将对部分栈和队列综合运用题进行讲解,以对栈和队列有一个更深层次的理解。 有效的括号 先来看题 思路分析 这里…