抖音客户端创作体验优化攻略

前言

本文侧重阐述的,是指标优化的流程,即如何在既有的业务目标下,按照科学的视角评估问题,经过一定的流程分析、分解问题,找寻合理方向和关键路径,最终解决问题,并给予收益评估。

1. 定义目标和评估方法

首先确定我们的业务目标 —— 抖音创作体验超越竞品,提升投稿率。如何定义“创作体验”和“超越”,我们需要将建设可量化评估的数据指标,并提供切实可信的评估方案。

首先围绕创作体验,我们建立了一套完整的数据指标体系,包括用户使用过程中的各种重要性能和体验指标,例如拍摄/编辑首帧、卡顿、帧率、各种分支能力(音乐/道具/贴纸等)的面板加载时长/下载时长/下载成功率等等,同时构建了创作体验-> 投稿率 -> DAU/留存 的贡献链路。如何找到这些技术指标,并区分其优先级和锚定其在评估体系中的权重,我们会在章节二中详细讲述。

1dca20ddad634f748611586e88afcdfe.png

评估方案上,我们采用了线下竞品评测+自动化的方案,采样线上机型分布,分高/中/低端机档位测试;然后将上述的一系列指标加权计算后得出一个体验评分。根据评分的数值来判定体验的排名和相对差距。评估过程中还会包括稳定环境、异常数据剔除、参数权重调整等通常手段,这里不再赘述。

ca2ce7994dbe4ecdd77c34cd66a8048f.png

2. 目标分解和相关性分析

章节一中我们提到了大量的数据指标,这些指标是如何挑选,又是如何确认其和业务相关的呢?

首先,一部分指标来源于脑爆和用户体验反馈,一部分来自于其他业务的经验(比如电商类业务的首帧对于页面转化率的影响,视频类APP的帧率对于用户留存的影响)和指标的拆解。例如对于投稿率提升的拆解,首先是数学拆分,类似电商类的成单拆解:

投稿率提升 = ∏(各步骤转化率提升) = 权限申请转化提升*页面1转化提升*...*发布成功率提升

然后是自下而上的化学分解,我们得到类似贡献链路:

首帧指标\帧率 ... -> 某页面转化率 -> 投稿率

这些指标和转化率都会体现在我们AB实验的过程中,例如某些实验由于功能渗透低、受其他因素(运营\商务\节日...)影响大,是没有显著投稿率提升贡献的,但是提升了部分环节的转化率,也可以体现出其对业务的收益,并支持全量上线。

然后,我们需要对这些指标做相关性分析来确认其对于投稿率的影响,从而挑选出真正影响用户体验的部分,并区分出优先级。

相关性是指两个变量因素的相关密切程度,需要注意的是相关性不代表因果关系。

9b16c39d0095d77ee160d8548080e8a1.png

如上是最基本的阶梯式相关性分析图,我们可以看到随着首帧时长的增加,页面转化率会一直走低,可以认为二者是具有相关性的,且在不同区间内相关密切程度不同。同时我们可以清晰的结合DAU分布看出,在 400~1000ms 区间,相关性非常高,DAU占比大,优化该区段的收益会非常显著;其次在 1500~1800ms区间,相关性非常高,DAU占比一般,优化该区段的收益会比较显著。我们还可以根据线下测试的不同档位的优化效果来预估线上的业务收益率:

线上业务收益 = 折扣系数 *  ∑(区段相关性斜率*(优化后分档-优化前分档))
注:实际操作中,预估收益和线上收益之间一般存在一个 0.5~0.7 的折损,不同的指标折损不同;

69f7fabb3a600f4db7194f5b310e03a5.png

分位式相关性分析稍微增加了下理解成本,但是实际应用和计算上更为清晰便捷;横坐标轴用分位数值(PCT 5\10\15...)替代了原来单位间隔递增的档位数值(100ms\200ms\300ms...),能更直接的计算出不同分段(DAU/分段数)带来的收益。

由于相关性不代表因果关系,在已确认了相关性的技术指标,且后续优化评估需要投入的资源要求非常高时,我们可以先用劣化实验确认下因果关系,甚至更准确的进行定量描述,以免过度投入却没有得到相应的收益。例如我们人为的制造某技术指标在某分段内由 a₁ 劣化到 a₂,通过AB实验验证线上业务指标由 P₁ 降低到 P₂,来反向推理假如技术指标在某分段内由 a₂ 优化到 a₁ ,线上业务指标会由 P₂ 提升到 P₁ 。

根据相关密切度、优化的收益预估和计算上工时后的投入产出比等数据,我们可以将已有的数据指标做一下优先级排序,作为后续优化项目排期的依据,并在竞品对比评测中给予不同的权重。

在具体优化的内容和手段上也是多种多样,比如性能优化、视觉优化等,接下来举两个优化实战的实例:

  • 抖音相册性能优化

  • 手机屏幕画质优化

3. 抖音相册性能优化

问题发现

相册是上传路径的第一个界面,业务场景非常重要,导入投稿占总投稿中的比例也很高,但是体验上存在较长时间的loading和封面加载缓慢的问题。

相册页原始的加载逻辑:

9ed182b6b25b96215aecfc57948355e1.png

优化手段1:使用 Scene 替代 Activity

Scene 是字节跳动的开源项目,可以替代 Activity、Fragment 对页面进行分割、跳转等。相册页使用的Activity作为载体,经测试发现一个空的Activity在中端机上面加载耗时就需要 50ms以上,使用Scene替换了Activity可以较好地降低这部分耗时。

优化手段2: 通过预加载/动态刷新来加载数据

如上图,我们可以看到我们相册显示前会有一个加载媒体数据的过程,所以我们针对这部分数据进行了一次预加载,由于抖音拍摄页右下角有一个相册的icon(通过查询用户相册最新的图片),所以我们通过复用减少了一次数据的查询。

在媒体数据查询中我们可以从 XXXColumns了解到系统提供给我们的所有的信息字段,当我们进行数据查询时,应该尽量的精简我们的查询字段,因为字段数量的多少会直接影响我们的加载速度。

public interface MediaColumns extends BaseColumns {
    // 省略部分代码 ...
    /**
     * The MIME type of the file
     * <P>Type: TEXT</P>
     */
    public static final String MIME_TYPE = "mime_type";
    /**
     * The height of the image/video in pixels.
     */
    public static final String HEIGHT = "height";
 }

当用户进入相册页后,就优先使用缓存展示相册信息,然后在子线程查询后通过 RecyclerView中的DiffUtil异步计算Diff后进行刷新。

优化手段3: Tab懒加载和封面加载

抖音的相册页使用的ViewPager,有三个Tab,但是我们知道ViewPager会默认加载页面的左右两页的。通过源码发现,ViewPager提供的 setOffscreenPageLimit 也并不能解决预加载的问题。所以通过重写PagerAdapter来实现Tab没有显示出来时候不加载任何内容。

public void setOffscreenPageLimit(int limit) {
    // DEFAULT_OFFSCREEN_PAGES = 1
    if (limit < DEFAULT_OFFSCREEN_PAGES) {
        Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "
                + DEFAULT_OFFSCREEN_PAGES);
        limit = DEFAULT_OFFSCREEN_PAGES;
    }
    if (limit != mOffscreenPageLimit) {
        mOffscreenPageLimit = limit;
        populate();
    }
}

抖音封面加载使用的是Fresco,封面加载如果有合适的媒体库的缩略图,就优先使用缩略。如果没有媒体库的缩略图的情况下,我们针对Fresco中的对图片和视频封面的加载进行了一系列的优化。

图片封面: 由于现在的照片普遍质量比较高,很多都达到了3-5M,对于一些中低端机,每次对原图进行resize也是比较耗资源的,所以我们采用了空间换时间,加载每一个图片时,给符合要求的图片缓存了一个resize后的图片,从而让中低端机的封面加载的更快。

视频封面: Fresco对视频抽帧使用的是 MediaMetadataRetriever,且并没有对视频封面抽帧做缓存,导致每一次视频封面都需要重新抽帧,所以视频封面相当的慢。针对这个我们可以通过两个个方式进行优化:  1.替换抽帧方式,可用多媒体相关库进行抽帧   2. 对抽帧出来的封面进行磁盘缓存。

public class LocalVideoThumbnailProducer implements Producer<CloseableReference<CloseableImage>> {
  // 仅展示关键抽帧逻辑
  @Override
  protected CloseableReference<CloseableImage> getResult() throws Exception {
      String path = getLocalFilePath(imageRequest);
      Bitmap thumbnailBitmap = ThumbnailUtils.createVideoThumbnail(path, calculateKind(imageRequest));
      return CloseableReference.<CloseableImage>of(new CloseableStaticBitmap(
          thumbnailBitmap,
          SimpleBitmapReleaser.getInstance(),
          ImmutableQualityInfo.FULL_QUALITY, 0));
  }
其它优化

除上面的优化以外,我们还做一系列的探索: 产品形态优化(如ins 相册只有9张图);厂商合作优化(手机厂商有封面的缓存私有接口,获取封面的Bitmap非常快);多个Tab复用RecycledViewPool;低端机切Tab时主动释放 释放Fresco Request;AndroidQ适配等一系列的优化,由于篇幅有限,就不赘述了。

优化后相册页的加载逻辑:

761cc19c638d458b5ba43e80ef794991.png

优化效果

测试条件

优化前

优化后




vivoNEX

8k张图、665视频

7fec802f77c40710d3c1bef3771561e3.gif

3dcd25696eadfd831259be45cd608232.gif

4. 手机屏幕画质优化

问题发现

手机屏幕小、计算资源有限、网络可靠性差(比如在地下室或者车站)、部分机型易发热的特点,使得移动设备很难在画质体验上与PC端相比较。如何在有限的条件下,尽量提升移动端画质体验,尤其是作为源头的视频投稿画质体验,是必须攻克的难题。为了解决这个问题,我们在硬件能力使用、编码参数调优、画质算法开发、产品策略的智能化上做了非常多的尝试,提出了一整套相对完整的解决方案

解决思路

硬件能力、画质算法、产品策略是移动端提升画质的三个主要途径。

86834bb2228b13ec64c44f5c95015e5b.png

解决途径1:硬件能力

硬件能力包括手机厂商为提升画质提供的基础能力,拍摄流程从前到后包括Camera能力、编解码能力、画质增强能力等。

  • Camera:防抖、自动曝光、夜景模式

  • 编解码:H264、H265的硬编硬解能力

  • 画质增强:HDR

303a2f6925f0251c05aaa95cabc3a4a8.png

解决途径2:画质算法

通过算法提升画质是一种实现无限可能的手段,包括超分、画质增强、降噪、插帧、调色等。

b506c0c9c0b2a22d4402d5afac6516c1.png

解决途径3:产品策略

全屏拍摄、高清、分级策略下发、视频透传等策略,通过产品设计,最大程度利用了屏幕、Camera采集、芯片、内存等硬件资源,通过软件策略的合理调度和精心设置,使得用户感官上的画质体验提升,主观上达到最满意的状态。

  • 全屏拍摄:摄像头画面最大程度撑满屏幕

  • 高清:提升分辨率和码率是提升画质有效的途径。

  • 分级策略下发:对不同能力的机型下发不同的策略。

d5f84dff60ccfdbd7eee08b1e5d58d0d.png

  • 视频透传:将用户相册中的文件高清文件不经过客户端转码,而直接上传,完整保留文件的高画质。

f0ce8f05b279fc1150bd14f1afba46a1.png

  • 画质评测:对多种场景进行画质评测,调整策略达到主观最优。

c34927a17d42c0cd4afc39e84641abb8.png

  • 分版本监控画质变化

d0b49220d9f75d870dc0dad2dbfef7da.png

总结

硬件资源、网络带宽和软件算法的不断升级,持续应用在移动设备上为画质的不断提升创造条件,画质的提升吸引用户将越来越多的时间花在短视频消费上;移动端短视频app作为内容视频化重要载体,逐渐变成软硬件前沿技术的重要应用场景,和互联网产品中的流量大户;用小屏幕创造的极致画质体验,成为技术和产品最佳的交汇点。

5. 监控和防劣化

日常数据采集和线上报警是我们监控线上性能和业务是否正常的重要手段,合理的报警阈值设置有助于我们及时发现线上问题,合理的采集和多维度分类有助于我们快速的定位问题并辅助分析解决。

举例来说,假如某省份的某CDN发生故障,或者某国家的网络异常,导致该节点的道具下发失败率&耗时增加,最终业务表现的可能是抖音/TikTok 整体投稿率下跌。那么我们反推一下,在线上出现投稿率下跌的时候,我们应该依赖哪些业务和性能埋点,才能快速的定位到出问题的是哪个功能和哪个 地区呢?这样反向思考的方式,也是构建埋点和监控体系的常见方法,这里就不展开去讲了。

相对优化而言,防劣化是很多APP研发流程中不够重视的一环,我们经常为了某些功能的快速上线和发版忽略了新代码带来的性能劣化,导致“有人填坑,有人挖坑”,“刚做了优化,又要做优化”。事实上,防劣化是和优化同等重要的工作。

抖音针对章节一中的指标体系,建设了一套完整的防劣化体系,包括P0级别的MR防劣化,P1级别的Daily Check和兜底的 Version对比:

2dc99743cca7874ed58dee0333021a1e.png

6. 常用分析工具

  • 通用(内存\cpu\网络\时延....):TraceView、Android profiler、DTrace、Instruments、SignPost、Hook;

  • 页面渲染\帧率:Profile GPU rendering、systrace;

  • 页面绘制\布局层次:Hierarchy Viewer ;

  • 内存\CPU分析:Memory Analyzer Tool、LeakCanary、System Trace。

推荐阅读

我是code小生,喜欢可以随手点个在看、转发给你的朋友,谢谢~

20d80d7d967659b89bbffa28274fcfa7.png

5897750364036f4704855878ad1e90cb.png觉得不错,请点个在看呀

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值