作者:醉仙
随着优酷业务的疾速倒退,随之而来的是模块数量的爆发式增长,根本每年以大量新增模块的速度减少,到目前为止优酷曾经有十分宏大的模块依赖。模块之间通信往往是互相间接依赖调用,以至于耦合非常重大且凌乱,每一个库依赖都是一颗“树”,甚至于一张“网”,对日常研发造成很多困扰:
插件化落地后果
iOS 模块插件化曾经全面在优酷落地,积淀出各业务线的轻量工程,大量的业务及架构插件,后续可依据不同业务需要,自在组装插件工程。以下是目前插件化工程落地后的一些收益:
-
间接收益
- 业务插件工程编译效率晋升 显著,本地编译工夫大幅升高,相干全副开发已应用起来;
- 通过插件组装生成业务插件工程,插件工程反对模拟器编译调试,并反对热重载;
- 模块工程和整包工程均应用插件作为依赖,彻底解决模块工程和整包工程依赖模块版本不统一状况,并反对依赖模块版本自动更新;
- 业务插件工程依赖库数量大幅缩小,且 pod 间接复用缓存,大幅晋升 pod 成功率及速度,磁盘占用大幅缩小;
-
间接收益
- 可提供运行内存、app 启动、功耗等插件卡口,常态化保持良好的用户体验;
- 所有插件反对自在组装,通过配置核心,提供疾速孵化极速版、国际版、Apple Watch、Apple TV 等 App 的能力;
- 依赖缩小,swift 断点调试时的 module 树疾速生成,断点效率晋升;
- 提速打包效率,建设插件工程构建平台,测试同学应用平台动静配置生成插件组合安装包即可进行测试。
插件是什么
- 插件是由一组模块聚合而成,同时也可依赖其余插件。在物理上,插件是一个文本形容文件,形容其蕴含的模块和插件信息;
- 插件基于 Xcode 工程,可独立编译并生成 App 产物,反对多插件自由组合。
简略插件
一个简略的插件能够仅由一个模块组成。
# 图片库插件
target 'Plugin' do
#模块 A
pod '模块 A','5.9.4'
end
简单插件
一个简单插件能够由一个或多个插件和模块组成。
# 插件
target 'Plugin' do
# 图片库插件
plug '1. 图片库插件'
#webp 图片解析模块
pod '模块 B','0.1.4'
#webp 根底模块
pod '模块 C','1.1.0.1'
end
为什么须要插件
和多个业务团队同学沟通后,咱们发现大部分的业务在性能调试时,往往只关注波及到本人须要迭代的业务性能,对于其余业务并不关怀。于是咱们想到能够基于整包工程,裁剪出一个只有单业务性能的 APP,这样编译速度必定会有极大的晋升。
裁剪 APP 须要对模块进行解耦,如果按模块颗粒度进行解耦,巨量模块进行解耦人力老本过高,而且过大的改变也会对线上稳定性有较大的影响。于是咱们对解耦粒度进行了放大,从模块解耦粒度放大到以插件为粒度进行解耦,这样咱们只须要解耦插件和插件之间的横向耦合关系,插件容许向下依赖其余插件,且插件外部模块也容许互相耦合,这样极大的的升高解耦的人力老本,也不便后续以插件维度进行依赖关系进行保护。
插件应用标准
插件聚合准则
- 业务插件:业务模块按业务性能维度划分边界,聚合成业务插件;
- 通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件;
- 架构性能插件:团体中间件模块、优酷中间件模块,按性能最小集划分边界,聚合成架构性能插件。
插件依赖准则
- 业务插件不容许横向依赖其余业务插件,容许依赖上层插件;
- 架构层插件不容许依赖下层插件,容许依赖上层插件及其他架构插件。
模块归属准则
- 一个模块仅能归属到一个插件,须要明确模块的职能;
- 同一个模块被多个插件依赖,须要思考下沉该模块为插件;
- 一个模块能够写成一个插件。
插件版本准则
- 每个插件没有版本的概念;
- 一个集成区的模块和版本对应一套插件中的模块和版本;
- 一套插件中的模块和版本默认和线上版本的集成区统一,也可设置并同步到最新集成区或历史集成区。
插件层级大图
基于以上插件的概念和应用标准,咱们对优酷 APP 架构进行插件化革新,从团体中间件到业务层,自下而上解耦聚合模块造成插件,最终积淀了大量插件和如下层级的 APP 架构。
- 业务实现层:对优酷现有的业务进行插件化革新,聚合成多个通用业务插件,通过业务插件和其依赖的通用业务插件、架构性能插件等大量插件,能疾速组合出一个轻量级业务 APP,用于晋升业务 Pod 速度和开发调试速度;
- 业务接口层:对优酷现有的业务进行横向解耦,造成多个业务接口插件,撑持下层业务插件横向解耦;
- 通用业务插件:通用业务模块按业务可复用最小集划分边界,聚合成通用业务插件;
- 架构性能插件:团体中间件模块、优酷中间件模块,按性能最小集划分边界,聚合成架构性能插件。
低成本管控计划
优酷所有模块曾经实现插件化革新,为了保障在后续版本迭代过程中,避免工程腐化,制订了一套低成本管控计划,能够自动更新插件内容,管控插件依赖关系。
插件自动更新
插件内容次要包含模块名称和模块版本号,每次版本迭代,插件都面临插件中模块的新增、删除、名称变更、版本变更等问题,优酷每个版本集成大量的模块,如果全副人工手动保护,老本将十分微小,所以咱们部署了一套主动同步及巡检服务,次要有以下目标:
- 插件中新增、删除模块自动更新;
- 插件中的模块版本号主动变更;
- 插件内容更新实现主动对所有插件进行编译巡检;
- 如果巡逻通过,插件合并到插件工程集成分支提供给业务插件工程应用;
- 如果巡逻失败,钉钉告诉失败信息(失败插件名称、编译失败日志链接、插件新增模块提醒)到钉钉群,不便疾速排查问题。
插件依赖管控
咱们基于插件的归属和层级,形象出规范的模块依赖关系数据,而后在模块构建打包时,减少依赖检测卡口,在每次模块构建过程中,执行依赖检测卡口,只有通过依赖检测的插件能力打包通过。
后果数据出现
构建提效
业务插件工程本地编译效率比照整包工程:
- 本地编译效率失去极大的晋升,均匀提效显著,本地编译工夫大幅升高,相干全副开发已应用起来。
计算公式:
- 编译提效公式:本地编译提效 = (整包工程构建时长 – 业务插件工程构建时长) / 整包工程构建时长
- 节约工夫公式:每月节约编译工夫 (8 小时工作日) = 插件工程月编译次数 均匀单次编译节约工夫 (秒) / (60 60 * 8)
模拟器反对
优酷存在局部模块不反对模拟器,导致优酷整包不反对模拟器,插件化革新后,业务在通过插件组装本人业务调试工程的时候,剔除这部分不反对模拟器的插件,使得业务插件工程能够应用模拟器进行调试。模拟器劣势:
- 一个企业号真机调试限度 100 台设施,而模拟器无限度;
- 模拟器反对所有 iOS 零碎,针对一些旧零碎开发和测试成本低;
- 模拟器反对热重载,无需编译和从新运行,批改代码保留即失效;
- 提前适配 iOS 新机型 UI。
磁盘占用
在模块插件化革新前,咱们只能应用整包工程进行开发,应用整包工程进行日常开发的时候,须要将所有模块下载,而插件化革新实现后,咱们从整包工程拆分出了多个业务插件工程,插件工程的模块数量相比整包工程大幅缩小,插件工程的磁盘占用相比整包工程大幅缩小。下图是整包工程和局部业务插件工程磁盘大小比照:
内存占用
插件化可提供运行内存、app 启动、功耗等插件卡口,常态化保持良好的用户体验,以播放页的运行内存为例,播放页有播放器、页面容器、弹幕、评论等性能,以前是对整个播放页计算内存值,而当初能够依照细碎的性能来计算内存值,别离失去播放器插件、播放页容器插件、弹幕插件、评论插件的内存值。
结语
综上所述,iOS 工程插件化是使用分而治之的思维,把一个简单的 App 分成多个子 App。通过子 App 可将研发聚焦于需要研发和用户体验晋升上。同时,插件化的拆装个性也进步了线上可复现问题的排查效率。因而插件化对研发效率以及开发幸福感的晋升都是十分有帮忙的。
关注【阿里巴巴挪动技术】,阿里前沿挪动干货 & 实际给你思考!