春争日,夏争时,扫码抽取夏日礼包!!! 了解详情
写点什么

服务 24 亿级用户 App 的大前端实践

  • 2021 年 5 月 24 日
  • 本文字数:3677 字

    阅读完需:约 12 分钟

服务24亿级用户App的大前端实践

茄子科技(海外 SHAREitGroup)是国内出海的先行者,2015 年成立后就“走出去”。2017 年,主要产品 SHAREit(国内茄子快传)全球用户总量超 12 亿,成为新兴市场的“国民应用”。截止目前,茄子科技产品矩阵全球累计安装用户量近 24 亿,覆盖 200 多个国家和地区,涵盖全球 45 种语言。


服务全球几十亿用户,茄子科技如何提升 App 的用户体验?怎样解决 App 的崩溃问题?如何应对海外复杂的网络问题?...... 针对上述问题,InfoQ 记者采访了茄子科技前端负责人。

提供高品质用户体验

用户体验是 App 应用的核心追求之一。在所有用户体验问题中,崩溃属于最高优先级。一旦出现崩溃,就意味着 App 彻底不可用,这会给用户体验造成非常大的伤害。

解决应用崩溃问题

据茄子科技前端负责人介绍,为解决崩溃问题,他们自建了一个 APM 平台,这样可以快速发现问题和协助定位问题。APM 平台的价值在于把人力从繁琐、重复性工作中解放出来,从而专注于问题本身。


在自建 APM 平台中,要着重提高的是客户端的抓取成功率和平台易用性。前者是为了尽量全面还原崩溃现场,后者是为了尽可能提升团队解决问题的效率。除了 APM 平台,要长期解决崩溃问题还需要人和一套持续运转的机制。


最初解决崩溃问题时,落脚点在于解决存量问题和遏制新增问题。首先,他们发起一场集中性战役——全力解决存量崩溃问题。经过一个阶段的治理,崩溃率下降到一个极低水平。其次,为防止崩溃率再次飙升,他们又开始了崩溃预防,把问题消灭在萌芽阶段:梳理出已解决的 Crash 问题,然后归类,并由点到面地思考总结出预防手段。


例如,针对服务端 API 脏数据引起的问题,统一在网络层进行校验和兜底;针对一些第三方库引发的问题,用 AOP 手段进行 Hook。


在交付流程中,添加编译检查阶段、自动化测试覆盖、更广的灰度触达等环节,尽可能将问题提前暴露。


即使问题发生在真实场景,APM 平台也能实现分钟级报警,并且自动把问题分配到相关同学。


茄子科技前端负责人表示,“我们以 APM 平台为依托,预防为主,建立了一套完善的响应机制”。

App 优化实践

除了应用崩溃,性能优化则是影响用户体验另一个关键。


据了解,茄子科技旗下的 SHAREit,其用户覆盖 200 多个国家和地区。不仅用户设备非常复杂,而且网络状况也不好,因此用户更容易遇到 App 卡顿、启动慢等体验类问题。


为解决这些体验类问题,他们首先搭建了基于线上的性能指标体系,充分衡量用户遇到的体验类问题。然后根据重要程度评估优先级,抓住重点,逐个击破。比如,在启动速度优化上,常规的优化手段作用有限,他们为此开发和落地了任务调度框架。所有启动任务通过任务调度框架进行调度,这样不仅可以充分利用启动阶段 CPU 的能力,而且还能方便地收集到每一个任务在线上的真实执行情况。之后根据任务执行情况,进行针对性调整。同时,他们还通过 ASM 收集到在启动阶段抢先执行的 Msg,然后与业务方一起确认并且后移。

网络优化

在网络层面,针对海外用户的网络环境复杂、质量较低等问题,茄子科技通过 HTTPDNS、协议优化、按需加载、CDN 预热、离线资源包和服务端渲染等方案,大幅提升网络请求的成功率。


考虑到 SHAREit 也是一个内容型产品,他们还在播放器层面进行优化,加入多码率预缓存策略、软硬解码自适应、动态追帧等技术,大幅提升视频相关的业务指标。

包体优化

在包体积方面,茄子科技进行过一次大的优化,应用包大小从 42M 缩减为 15M。据悉,包体优化主要分为两个方面:技术层面和业务层面。在技术上,他们采取了五项举措:


一是删减无用代码、资源,精简第三方库;二是代码层面的统一优化,比如 R 文件删除、使用 R8;三是图片压缩、格式转换和剔除重复图片;四是资源的混淆;五是 dex 的再次压缩。


在业务上,梳理出 App 的整体功能,下掉了渗透率较低的功能,并且对重点功能均实现 Bundle 化,这样在减小包大小的同时,也方便在不同国家的精细化运营。并且,技术同学为业务同学提供专门工具,从技术视角支撑和指导业务的优化方向。


茄子科技前端负责人表示,体验类的优化工作并不只涉及技术,单纯的技术优化非常容易遇到瓶颈或遇到无法推动业务方修改的困境,从而无法实现优化收益最大化。因此,他们在 SHAREit 的实践首先是调整项目定位,由技术同学主导,加入业务同学,统一战线。在更高层面统一双方目标,技术同学负责发掘优化项,提供工具和具体方案,业务同学负责更大规模的落地,各自发挥优势,双方共担项目,共享成果。


除了启动、网络优化、包体优化外,他们还对卡顿、内存、布局、电量、存储和线程等性能的多个维度进行优化,“我们的追求就是让用户在使用产品时有一个高品质体验”。

前端工程化建设:从石器时代到信息时代

前端工程化,通俗的理解是,尽可能快速地实现可信赖的产品。其中两个关键词,“快速”,讲求开发速度、构建速度、测试速度、问题定位速度;“可信赖”,包括代码的质量、产品的性能、安全、及重现和定位问题能力。茄子科技前端负责人介绍,SHAREit 的前端工程化建设经历了三个阶段:石器时代,工业时代,信息时代。

石器时代

在石器时代,典型特征是单工程的 MVC 架构,公司发展初期人比较少,反而效率更高,问题也比较少。但随着公司发展越来越快,SHAREit 从单业务发展到多业务的平台型产品时,单工程架构在人员节奏方面出现了较多问题,如代码耦合导致一些问题浮现出来。这时,便开始工程组件化重构,进入到工业化时代。

工业时代

工业化时代,典型的特征是组件化。茄子科技使用的是多工程、多仓库的方案,每个组件或 SDK 都有自己独立的仓库,都可以独立于主工程进行单独的编译和运行。这方面分为三大层:APP 的壳、业务层、基础层,基础层再往下还有更多、更细粒度的划分。前端团队自上而下通过 AAR 的方式进行依赖。组件化采用“分而治之”的思想,很好地解决了多团队协同作战的问题。

信息时代

随着公司孵化更多产品,每个产品在不同国家定制不同功能,规模越来越大了,用以前的组件化形式很难高效地支撑现有的业务,于是,茄子科技引入了 GoogleBundle 技术,进入到信息化时代。其实针对这一问题,国内多采用插件化的方案,但由于海外不能做插件化技术,茄子科技只能运用谷歌自有特性。在信息化时代,典型的特征是 Bundle 组件化。Bundle 模块具有反向依赖的特征。通过增加 Bundle 壳及自动化检测工具的形式,让 AppBundle 的特性和以前已有的组件化融合,让开发者保持已有的开发模式。通过 AppBundle,可以做到针对每个国家用一个 APP 按需定制不同功能,如内容、直播、游戏等。为提升效率和质量,茄子科技还搭建了客户端 CI/CD 平台,流程主要有编码规范检测、大文件 / 图片检测、静态代码扫描,关键文件触发 Review、代码 Review、安全风险检测,预编译、包体积监控,编译速度监控等,能做到自动打包、自动检测、自动化测试与发布。


据悉,前端团队已经涵盖开发、测试、构建、部署一系列流程,通过自研 APM 系统的预警机制、自动分配、辅助信息等,能够及时发现且快速定位问题,并优化迭代,最终形成整个研发流程闭环。

Bundle 技术的应用与实践

2019 年,茄子科技前端团队开始接触 Bundle 技术,并在当时做了试点。通过这次尝试,他们发现 Bundle 模块的开发、编译和发布等都与原来的 Library 形式有很多不同。因此,他们做了 Bundle 组件化。


据悉,他们将 Bundle 的开发、编译、发布等特性与现有组件化方式融合,让业务开发者保持原有开发模式对 Bundle 的特性几乎无感知。


在具体实践中,茄子科技前端团队做了四件事:


第一,为每个 Bundle 组件增加一个壳。Bundle 组件还是以原有的 Library 开发和发布。Bundle 壳依赖 App 壳和 Bundle 组件。Bundle 壳中只是配置了 Bundle 的集成属性,无任何逻辑代码。这样很好的解决了 Bundle 模块反向依赖宿主的特性。


第二,资源隔离。Bundle 组件与宿主资源隔离,不能互相访问。针对这种情况,他们做了自动化检测工具,将问题暴露在编译阶段。


举个例子,GameListFragment 是 Bundle 组件的代码,继承了 BaseRequestListFragment(宿主的基础 SDK 代码)。其布局资源文件使用了 ActionPullToRefresh 控件。



当调用 findViewById(R.id.pull_to_refresh) 时,Bundle 组件调用了宿主资源,这样编译是可以通过的,但是会在运行时出现问题。解决办法是由子类提供 getXXId 方法,父类复写即可。



第三,APT/AOP 等第三方库不好用,他们通过修改其源码进行适配。比如使用的 Android 路由框架 Router,修改其自定义的 GradlePlugin 的扫描 Scope,让它可以扫描到 Bundle 组件及其依赖。此外,通过 Bundle 模块安装状态,判断是否将 apt 生成路由信息注入到 ServiceLoaderInit,保证有无 Bundle 模块时,路由信息都可以成功注册。


第四,线下模拟真实的 Bundle 模块组合。结合 CI/CD 在打包时,增加按国家、语言等多种维度的产出 aab 集合,方便测试人员在线下测试各种 Bundle 模块组合成 aab 的情况。


结果,Bundle 组件化的实施不仅极大减小了应用包大小,SHAREit 从原来的 42M 缩小到 15M。而且,App 实现了动态按需下发,除本身支持的国家、语言、屏幕等之外,还会按照需求下发,比如创作者中心模块只有在创作者登录后才会有入口引导下载。

2021 年 5 月 24 日 16:401714
用户头像
万佳 InfoQ编辑

发布了 651 篇内容, 共 265.2 次阅读, 收获喜欢 1716 次。

关注

评论

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

Java基础 | 泛型机制与反射原理

知了一笑

Java jdk 反射 泛型

各地力推“链长制”,区块链让产业链更加安全可靠

CECBC

ElasticSearch集群的概念及搭建过程,Java程序员晋升路线

Java 程序员 后端

ELK太重?试试KFC日志采集,2021大厂Java面试经验

Java 程序员 后端

Java基础 | Proxy动态代理机制详解

知了一笑

jdk 动态代理 java基础 Proxy

Windows11 搭建openvino_tensorflow环境

IT蜗壳-Tango

IT蜗壳 OpenVINO 11月日更 openvino_tensorflow

git(3)Git 分支,mysql语句优化面试题

Java 程序员 后端

Go语言安装和配置SDK,阿里牛逼

Java 程序员 后端

Flink SQL Client综合实战,深入理解java虚拟机百度云

Java 程序员 后端

Redis Pipeline

new life

GitHub标星17万:打破程序员“中年危机,单点登录(Single-Sign-On)解决方案

Java 程序员 后端

.NET6新东西--ConfigurationManager

喵叔

11月日更

Flink的sink实战之四:自定义,Java开发笔试题目

Java 程序员 后端

WEB本地存储:localStorage、Web SQL Database、IndexedDB

devpoint

Cookie indexedDB LocalStorage sessionStorage 11月日更

GitHub上标星75k+的《Java面试突击版,京东java面试题答案

Java 程序员 后端

Github限时开放!阿里内部强推的《微服务容器化参考指南

Java 程序员 后端

ELK + Filebeat + Kafka 分布式日志管理平台搭建,最新java面试题及答案

Java 程序员 后端

【Promise 源码学习】第二篇 - Promise 功能介绍与特性分析

Brave

源码 Promise 11月日更

Github上堪称最全的面试题库(Java岗)到底有多香,java基础进阶视频

Java 程序员 后端

《Kubernetes in action 读书笔记》:Kurbernetes横空出世

后台技术汇

kubenetes 11月日更

Gradle项目的jar发布到私有仓库,java并发编程实战王宝令

Java 程序员 后端

Elasticsearch聚合的嵌套桶如何排序,java架构和框架

Java 程序员 后端

flume基本概念与操作实例(常用source),kalilinux视频教程

Java 程序员 后端

外包学生管理系统详细架构设计

天天向上

架构实战营

数据分析入门

加哥

大数据

Flink处理函数实战之一:深入了解ProcessFunction的状态(Flink-1

Java 程序员 后端

Git 常用命令,使用Docker部署Spring-Boot项目

Java 程序员 后端

Github上都在疯找的阿里内部“全栈技能修炼”终于来了,kafka基础概念

Java 程序员 后端

GitLab CI构建SpringBoot-2,rabbitmq原理及作用

Java 程序员 后端

Elasticsearch聚合的嵌套桶如何排序(1),java大学基础教程

Java 程序员 后端

Geospatial-地理空间,java面试基本知识

Java 程序员 后端

服务24亿级用户App的大前端实践_移动_万佳_InfoQ精选文章