拒绝编译等待 - 动态研发模式 ARK
作者:字节跳动终端技术——徐纪光
背景
iOS 业界研发模式多为 CocoaPods + Xcode + Git 的多仓组件化开发模型。为追求极致的研发体验、提升研发效率,对该研发模式进行了大量优化,但目前遇到了以下瓶颈,亟需突破:
- pod install 时间长:编译优化绝大部分任务放在了 CocoaPods 上,CocoaPods 承担了更多工作,执行时间因此变长。
- 编译时间长:虽然现阶段绝大部分工程已经从源码编译转型成二进制编译,但编译耗时依旧在十分钟左右,且现有工程基础上已无更好优化手段。
- 超大型工程通病:Xcode Index 慢、爆内存、甚至卡死,链接时间长。
如何处理这些问题?
究其本质,产生这些问题的原因在于工程规模庞大。据此我们停下了对传统模式各节点的优化工作,以"缩小工程规模"为切入点,探索新型研发模式——动态研发模式 ARK。
ARK[1] 是全链路覆盖的动态研发模式,旨在保证工程体验的前提下缩小工程规模:通过基线构建的方式,提供线下研发所需物料;同时通过实时的动态库转化技术,保证本地研发仅需下载和编译开发仓库。
Show Case
动态研发模式本地研发流程图如下。接下来就以抖音产品为例,阐述如何使用 ARK 做一次本地开发。
演示基于字节跳动本地研发工具 MBox[2] 。
流程图
仓库下载
ARK 研发模式下,本地研发不再拉取主仓代码,取而代之的是 ARK 仓库。ARK 仓库含有与主仓对应的所有配置,一次适配接入后期不需要持续维护。
相较传统 APP 仓库动辄几个 GB 的大小,ARK 仓库贯彻了缩减代码规模这一概念。仓库仅有应用配置信息,不包含任何组件代码。ARK 仓库大小仅 2 MB,在 1 s 内可以完成仓库下载 。
在 MBox 中的使用仅需几步点击操作。首先选择要开发的产品,然后勾选 ark 模式,选择开发分支,最后点击 Create 便可以数秒完成仓库下载。
开发组件
CocoaPods 下进行组件开发一般是将组件仓库下载到本地,修改 Podfile 对应组件 A 为本地引用 pod A, :path =>'./A'
,之后进行本地开发。而在 MBox 和 ARK 的研发流程中,仅需选择要开发的组件点击 Add 便可进行本地开发。
动态研发模式 ARK 通过解析 Podfile.lock
支持了 Checkout From Commit
功能,该功能根据宿主的组件依赖信息自动拉取相应的组件版本到本地,带来便捷性的同时也保证了编译成功率。
pod install
传统研发模式下 pod install
必须要经历 解析 Podfile 依赖、下载依赖、创建 Pods.xcodeproj
工程、集成 workspace 四个步骤,其中依赖解析和下载依赖两个步骤尤为耗时。
ARK 研发模式下 Podfile
中没有组件,因此依赖解析、下载依赖这两个环节耗时几乎为零。其次由于工程中仅需开发组件步骤中添加的组件,在创建 Pods 工程、集成工程这两个环节中代码规模的降低,对提升集成速度的效果非常显著。
没有依赖信息,编译、链接阶段显然不能成功。ARK 解决方案通过自研 cocoapods-ark 及配套工具链来保证编译、链接、运行的成功,其原理后续会在系列文章中介绍。
开发组件编译&调试
和传统模式一样通过 Xcode 打开工程的 xcworkspace
,即可正常开发、调试完整的应用。
工程中仅保留开发组件,但是依然有变量、函数、头文件跳转能力;参与 Index、编译的规模变小,Xcode 几乎不存在 loading 状态,大型工程也可以秒开;编译速度大幅提升。在整个动态研发流程中,通过工具链将组件从静态库转化成动态库,链接时间明显缩短。
查看全源码
ARK 工程下默认只有开发组件的源码,查看全源码是开发中的刚需。动态研发流程提供了 pod doc
异步命令实现该能力,此命令可以在开发时执行,命令执行完成后重启工程即可通过 Document Target 查看工程中其他组件源码。
pod doc 优点:
- 支持异步和同步,执行过程中不影响本地开发。
- 执行指令时跳过依赖解析环节,从服务端获取依赖信息,下载源码。
- 通过
xcodegen
异步生成 Document 工程,大幅降低pod install
时间。 - 仅复用
pod installer
中的资源下载、缓存模块。 - 支持仓库统一鉴权,自动跳过无权限组件仓库。
收益
体验上: 与传统模式开发流程一致,零成本切换动态研发模式。
工具上: 站在巨人的肩膀上,CocoaPods 工具链相关优化在 ARK 同样生效。
时间上: 传统研发模式中,历经各项优化后虽然能将全链路开发时间控制在 20 分钟左右,但这样的研发体验依旧不够友好。开发非常容易在这个时间间隔内被其他事情打断,良好的研发体验应该是连贯的。结合本地开发体验我们认为,一次连贯的开发体验应该将工程集成时间控制在分钟级,当前研发模式成功做到了这一点,将全链路开发时间控制在 5 分钟以内。
成功率: 成功率一直是研发效率中容易被忽视的一个指标。据不完全数据统计,集团内应用的本地全量编译成功率不足五成。一半的同学会在首次编译后执行重试。显然,对于工程新手来说就是噩梦,这意味着很长时间将在这一环节中浪费。而 ARK 从平台基线到本地工具链贯彻 Sandbox 的理念,整体上提高编译成功率。
写在最后
ARK 当前已经在字节跳动内部多业务落地使用。从初期技术方案的探索到实际落地应用,遇到了很多技术难点,也对研发模式有了新的思考。
相关技术文章将陆续分享,敬请期待。
扩展阅读
[1] ARK: https://github.com/kuperxu/KwaiTechnologyCommunication/blob/master/5.WWDC-ARK.pdf
[2] MBox: https://mp.weixin.qq.com/s/5_IlQPWnCug_f3SDrnImCw
字节跳动终端技术团队(Client Infrastructure)是大前端基础技术的全球化研发团队(分别在北京、上海、杭州、深圳、广州、新加坡和美国山景城设有研发团队),负责整个字节跳动的大前端基础设施建设,提升公司全产品线的性能、稳定性和工程效率;支持的产品包括但不限于抖音、今日头条、西瓜视频、飞书、懂车帝等,在移动端、Web、Desktop等各终端都有深入研究。
火山引擎应用开发套件MARS是字节跳动终端技术团队过去九年在抖音、今日头条、西瓜视频、飞书、懂车帝等 App 的研发实践成果,面向移动研发、前端开发、QA、 运维、产品经理、项目经理以及运营角色,提供一站式整体研发解决方案,助力企业研发模式升级,降低企业研发综合成本。
拒绝编译等待 - 动态研发模式 ARK的更多相关文章
- Java-马士兵动态代理模式
Java-马士兵动态代理模式 模拟jdk的动态代理的实现原理, 这些东西没有必要写出来,写项目的时候一般用不上,主要是为了面试和理解原理: java动态代理有什么作用 作用非常大,在很多底层框架中都会 ...
- [转载]Web 研发模式演变
原文链接:https://github.com/lifesinger/blog/issues/184 前不久徐飞写了一篇很好的文章:Web 应用的组件化开发.本文尝试从历史发展角度,说说各种研发模式的 ...
- Web 研发模式演变
前不久徐飞写了一篇很好的文章:Web 应用的组件化开发.本文尝试从历史发展角度,说说各种研发模式的优劣. 一.简单明快的早期时代 可称之为 Web 1.0 时代,非常适合创业型小项目,不分前后端,经常 ...
- Qt 4.7.4 完美动态编译发布动态调试,以及静态编译发布
首先是准备工作,去QT主页下载独立的QT类库安装包以及完整QT SDK安装包,还有QT Creator for windows 版 下载地址:http://qt.nokia.com/downloads ...
- 读 《 Web 研发模式的演变 》与《Javascript:世纪机器语言》
读了两篇文章,内心还是很震撼的,在这之前,我学习知识都是直接找教程,翻阅资料,写几个小demo,没有去了解我所学的东西的发展历程,<Web研发模式的演变>这篇文章讲述了web的前世今 ...
- java jdk动态代理模式举例浅析
代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...
- Web 研发模式的演变
前不久徐飞写了一篇很好的文章:Web 应用的组件化开发.本文尝试从历史发展角度,说说各种研发模式的优劣. 一.简单明快的早期时代 可称之为 Web 1.0 时代,非常适合创业型小项目,不分前后端,经常 ...
- .Net Core Razor 预编译,动态编译,混合编译
预编译 预编译是ASP .Net Core的默认方式.在发布时,默认会将系统中的所有Razor视图进行预编译.编译好的视图DLL统一命名为 xxx.PrecompiledViews.dll 或者 xx ...
- apache 静态编译和动态编译参考
apache-2.2.22 编译安装笔记 一.静态编译 在使用./configure 编译的时候,即没有使用--enable-mods-shared=[module]或者--enable-[m ...
随机推荐
- 【LeetCode】1033. Moving Stones Until Consecutive 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 脑筋急转弯 日期 题目地址:https://leet ...
- 【LeetCode】887. Super Egg Drop 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 参考资料 日期 题目地址:https://leetc ...
- LeetCode1239串联字符串的最大长度
题目 给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解. 请返回所有可行解 s 中最长长度. 解题 ...
- Docker 与 K8S学习笔记(四)—— Dockerfile的编写
在上一篇中我们简单介绍了Docker镜像的获取与使用,其中在镜像制作中提到在实际使用中一定要用Dockerfile方式去创建镜像而不要用docker commit方式,那么我们该如何编写Dockerf ...
- Codeforces 777E:Hanoi Factory(贪心)
Of course you have heard the famous task about Hanoi Towers, but did you know that there is a specia ...
- .NET+Sqlite如何支持加密
.NET+Sqlite如何支持加密 Sqlite SQLite 来源于公共领域 SQLite Is Public Domain. 确保代码不会受到任何专有或许可内容的污染,没有任何来自互联网上的未知来 ...
- Differential Evolution: A Survey of the State-of-the-Art
@ 目录 概 主要内容 DE/rand/1/bin DE/?/?/? DE/rand/1/exp DE/best/1 DE/best/2 DE/rand/2 超参数的选择 的选择 的选择 的选择 一些 ...
- <数据结构>XDOJ314.完全二叉树的子树
问题与解答 问题描述 对一棵完全二叉树,采用自上而下.自左往右的方式从1开始编号,我们已知这个二叉树的最后一个结点是n,现在的问题是结点m所在的子树一共包括多少个结点? 输入格式 输入数据包括多行,每 ...
- 【jvm】08-垃圾回收器那么多傻傻分不清?
[jvm]08-垃圾回收器那么多傻傻分不清? 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...
- JAX-MD在近邻表的计算中,使用了什么奇技淫巧?(一)
技术背景 JAX-MD是一款基于JAX的纯Python高性能分子动力学模拟软件,应该说在纯Python的软件中很难超越其性能.当然,比一部分直接基于CUDA的分子动力学模拟软件性能还是有些差距.而在计 ...