小扎和马斯克的“格斗”,从八角笼中来到了社交平台上。
当地时间 7 月 5 日,Meta 旗下的 Instagram 正式发布 Threads,与 Twitter 展开直接竞争。据介绍,Threads 的定位是“用文本分享动态和加入公共对话”。应用上线后,Meta 公司首席执行官马克·扎克伯格“实时”公布 Threads 最新成绩:4 小时,注册用户 500 万;7 小时,注册用户 1000 万;24 小时,注册用户 3000 万;48 小时,注册用户 7000 万。
北京时间 7 月 10 日 15 点左右,据数据追踪网站 Quiver Quantitative 披露,Threads 的登录用户数已经突破 1 亿人。扎克伯格表示,这主要是自然需求,Threads 甚至还没有开展很多推广活动。这远远超出了预期。
而此时,距离 Threads 在美洲地区首发上线连 5 天整都没到。Threads 的注册用户增速也打破了此前 ChatGPT 留下的记录,后者用了 2 个月实现注册用户数破亿。此外,Threads 用户的活跃度也很高,据报道,过去几天 Threads 上的帖子数量已经达到 9500 多万条,点赞数 1.9 亿次。
投资银行 Evercore ISI 表示,虽然现在还处于早期阶段,但预计 Threads 可以为 Meta 带来可观的现金。Threads 有望在未来两年内覆盖近 2 亿的日活跃用户,并产生约 80 亿美元的年收入。
那么,这样一款现象级应用程序是如何构建的?
Threads 是如何构建的?
近日,国外工具分析平台 Emerge Tools 率先对 Threads App 进行了拆解分析,分别揭晓了 Android 版 Threads 以及 iOS 版 Threads 是如何构建的。
Emerge Tools 表示,Meta 投入大量资源对应用做移动性能优化。通过测试和分析,可以看到 Meta 的移动应用优化确实做得不错。Meta 采取的不少模式虽非典型的最佳实践,但凭借着强大的基础设施和工程能力,Meta 仍然在这场“以终为始”的性能大战中占据了主动。
拆解 Android、iOS 版 Threads
Android 版 Threads 方面,跟其他 Meta 应用一样,Threads 也提供通用 APK 文件。虽然业界认为 AAB 才是最佳实践,但 Meta 还是选择了高度优化过的通用 APK——把资源、自定义打包共享库和 Redex 结合了起来。
Threads 还发布了调试代码。Threads 提供 com.instagram.debug.devoptions.sandboxselector 和 com.instagram..debug.quickexperiment 等调试包。
此外,Threads 在应用的某些部分使用了 React Native,- InstagramBundle.js.hbc.spk.xz 可能是 Hermes 字节码(js.hbc)的压缩版本。
其中有个很大的.spo 文件,看起来像是不同本机库的编译版本。其中附带一个元数据文件:
Emerge Tools 猜测这个.spo 文件是所有本机库的合并版本,第二个条目是 offset/size,第三个条目则是 checksum。
UI 方面,根据 @richz(Threads 工程师)的帖子,Threads 主要用 Jetpack Compose 来构建自己的 UI。跟整个 dex 大小相比,dex 的组装部分相对较小(约 130 KB),所以也许能更高效地使用 Compose 并/或共享 Instagram 代码、控制实际代码量。
Threads 的 iOS 版有两点比较突出:
Thredas 有 0 个动态库,而 Facebook 应用却大量使用动态框架。
Threads 的插件体量几乎逼近人们的认知极限。其中 BarcelonaShareExtension 达到 81 MB。相比之下,最大的 Instagram 插件- InstagramNotificationExtension 也仅为 23.5 MB,InstagramShareExtension 则为 5.6 MB。
后端采用 Cinder,基于 Python 3.10 构建
此外,据 CPython 核心开发者 Łukasz Langa 透露,Threads 的后端使用了 Cinder,这是基于 Python 3.10 构建的高性能版本,其中包含 JIT、延迟加载模块、预编译静态模块,而且针对 Python 3.10 做出了一系列有趣的调整。
据了解,Cinder 是 Meta 内部打造的、强调高性能的 CPython 3.10 生产版本。其中包含多种性能优化,例如字节码内联缓存、协和即时评估、每次一个方法 JIT,以及使用类型注释在 JIT 中实现类型专用字节码、从而提高性能的实验性字节码编译器。
Cinder 目前已经在支持 Instagram,而且正越来越多被用在 Meta 公司的各类 Python 应用程序当中。Meta 表示,公开发布 Cinder 是为了推动将部分工作负载回流至 CPython 的讨论,同时努力减少 CPython 开发者在性能优化方面浪费的时间。
但 Cinder 本身尚不完善,也不是 CPython 的替代品,Meta 发布项目代码的唯一理由,就是想帮助 CPython 在速度方面更上一层楼。虽然 Meta 自己确实在生产环境中运行 Cinder,但无法为其他开发者提供生产层级的技术支持。只能保证 Cinder 在 Meta 自己的生产工作负载中稳定且快速,但不保证其在其他外部工作负载或用例中具有良好的稳定性、正确性或性能。
据介绍,Instagram 拥有非常庞大的 Python 代码库,所以由引用计数复制所带来的开销也极为沉重。为此,Cinder 开发出名为“不朽实例”(Immortal Instance)的解决方案,能够从引用计数中清退对象。此功能通过定义 Py_IMMORTAL_INSTANCES 进行控制,并在 Cinder 中默认启用。这对生产流程是一个巨大的胜利(节约开销约 5%),但也会令直接代码的运行速度变慢。由于引用计数操作会频繁发生,所以启用此功能前必须检查对象是否确实参与了引用计数。
Threads 的启动时间如何?
Emerge Tools 用 ETTrace 来查看 Threads 的实际启动时间。
使用 ETTrace 为 Threads 的启动过程生成火焰图。
Emerge Tools 表示,由于 Meta 公开的 build 混淆,能从栈中追踪到的信息不多。但仍然可以看到,其中存在大量 pre-main 时间(在追踪期间约为 50 毫秒)。
还有一个会在应用启动时初始化的 WKWebView,它的速度也相当慢。这意味着整个登录体验并非本机、而是在显示 webview,或者是出于追踪的目的而将登录放在了后台。
Threads 未来会“去 Instagram 化”吗?
分析发现,Threads 在 Android 和 iOS 两大平台上都照搬了不少 Instagram 代码,比如 InstagramBundle.js.hbc.spk.xz 等等。
其中,Android 版 Threads 与 Instagram 间的/assets/dsp 也是相同的。考虑到 Threads 与 Instagram 高度集成,二者共享代码也完全在情理之中。
此外,iOS 版 Threads 的 BarcelonaShareExtension 与 Instagram 的 FBSharedFramework 之间拥有很多相同元素。一些值得注意的相同元素:
FilterAsset.bundle;
ig_signals_cupid_better_recall_v1.mlmodelc 与 ig_signals_cupid_v2.mlmodelc;
资产目录几乎完全相同。
作为一款新产品,Threads 的发布显然有些仓促。Threads 在 Android 和 iOS 两大平台上和 Instagram 共享大量代码,明显是为了加快开发速度。Threads 团队希望快速行动,在一切可能的位置直接使用 Instagram 那边的现成代码。在未来的发展中,Threads 会不会逐步“去 Instagram 化”值得关注。
目前,Threads 还缺少了一些关键功能,比如没有翻译按钮、不能搜索内容(只能搜索用户)、没有话题标签功能、没有编辑按钮(发布帖子后无法进行编辑)、不能私信等。Meta 产品副总裁 Connor Hayes 也承认,有一些功能没能赶上这次发布,它们会在日后更新时推出。
参考链接:
https://twitter.com/llanga/status/1676846870520291329
评论