Recce-Host 布局逻辑迁移复盘

工作实践约 15 分钟

核实日期:2026-10-13。材料通过学城 CLI 直读原文核对,未引用二手转述。这条线 2025-07 规划,2025-12 与 2026-01 完成两次上线,本文按上线结果回看规划。

写在开头:这次最值得记的是什么

上一份复盘讲「怎么把范围划清楚」,这份讲另一半:怎么判断一个没有当下痛点的改造值不值得做。

《Recce-Host 布局逻辑迁移规划》给了四条理由,性能排第一——跨语言调用从 N+2 次降到 N+1 次。这是四条里唯一可测的。实测两端给出相反的答案:Android 从 340.8ms 变 418.4ms(慢了),鸿蒙极端页 host 布局从 17.826s 降到 0.694s(快约 26 倍)。两端的成因都不在架构——一边是新增成本没结清(多解析一次数据建影子树 +72ms、主线程队列未优化 +70ms),一边是被替换的旧实现本来就慢。

用性能论证这类改造,等于把结论交给「被替换掉的旧实现有多差」这个偶然变量。

换一个端、换一个页面,符号都可能翻转。规划真正兑现的是那两条本来就测不出来的——三端共用一套布局计算代码,为将来换布局框架(taffy 这类)预留接口。它们不需要 benchmark,也不该用 benchmark 来论证。

另一条更实操:能不能回滚,决定要不要拆成两次发布。 yoga 直接升级、没有开关,出问题只能把 white list 置空强制降级;host 新架构有 horn 开关,随时可退。两件事因此拆成鸿蒙点评 11.51.0(yoga)与 11.55.0(host)两次上线。

一张表看完

问题这份规划给出的答案
这事该不该做四条理由三条不可测;唯一可测的性能,两端实测符号相反
真正的收益在哪三端共用一套布局计算代码、为换布局框架留接口——都不需要 benchmark
怎么上线拆两次:没开关的先上(yoga),有开关的后上(host)
选哪个端做验证不是越低越好,量级要够暴露问题——最终选点评(日均 3.35 万)
怎么验收与旧架构行为一致,不是「符合理想」

词表

词意思
host 层 / platform 层Recce 把渲染拆两层:host 层(Rust)跑布局计算,platform 层是各端原生侧,负责真实视图与事件
影子树(shadownode 树)连接 Yoga 树与真实视图的中间层,维护布局相关信息;它归谁,就是这次迁移的核心
跨语言调用host 层与 platform 层之间的数据传递,是这份规划给性能定的标尺
useNewArchitecture新老架构的埋点字段与开关标识,1 走新架构、0 走旧架构;改开关要杀 App 重启才生效
等价验收迁移类改动的判据是「与旧实现行为一致」,而不是「符合理想效果」

一、这是一件什么事:为未来铺路的改造

Recce 的布局计算是 Yoga,架构是三棵树:View 树(platform 层的真实视图)、影子树(platform 层,维护布局信息并与 host 通信)、Yoga 树(host 层,负责最终布局计算)。要动的,就是影子树的位置。

规划给了四条理由,只有一条可测:

理由具体内容能不能测
业务现有 Flex 够用,但将来有框架或业务方要 CSS Grid 时 Yoga 不支持,会「处于比较被动尴尬的局面」;迁移是为低成本甚至无缝替换布局框架未来向,测不了
性能省一次跨语言调用(视图创建从 N+2 次降到 N+1 次)能测——实测两端符号相反
人力三端共用一套布局计算代码测不了
架构platform 层只留渲染与交互、host 层布局计算闭环,两头都能低成本换测不了

行业对照也列了:React Native 用 Yoga 只支持 Flex;Dioxus 用 taffy,Flex 与 Grid 都支持,但 Flex 样式集不支持 RTL;clay 也只支持 Flex。「迁移是为了能换 taffy」这条因果链在前面那份 Yoga 复盘里也有——Yoga 方案里否掉「换成 Taffy」时写的原话,就是「这个事情可以等到布局计算迁移之后」。

图 1:迁移前后两层职责的变化,以及省与增两笔账
图 1:迁移前后两层职责的变化,以及省与增两笔账

二、方案:改动两处,代价一处

技术方案把改动收敛成两条:树结构上,影子树从 platform 层挪到 host 层;数据传递上,host 传给 platform 的数据要额外带上算好的布局信息。

代价藏在一句细节里,方案自己写了,但没和收益放在一起算:

账内容
省下的视图创建的跨语言调用从 N+2 次降到 N+1 次(布局计算那趟不再跨层)
新增的数据解析从 1 次变成 2 次(host 建影子树解析一次、platform 建视图又解析一次)

方案里「从性能上看」这一节只写了两个字:暂定。也就是说,做方案时这笔账并没有结清——省下的一次调用写进了正文,新增的一次解析写进了方案细节,两笔从未合在一起算。它后来成了这份规划最需要解释的地方。

风险列了三条:三端兼容性方案设计困难(鸿蒙已做一版,统一数据传输棘手)、删除节点这类细节麻烦(platform 层强依赖影子树,而影子树搬走了)、布局框架切换的接口设计繁重。

三、实测:Android 慢了,鸿蒙快了 26 倍

三组数据都在游乐场用新老架构对照跑,同一个开关切换、同一份 bundle。

场景旧架构新架构差差在哪
Android 基准页(启动到第一帧)340.8ms418.4ms慢 78mshost 层 +72ms(多解析一次数据、建 shadownode),platform 层 +70ms(主线程任务队列未优化)
鸿蒙基准页(286 个组件)477.6ms460.4ms快约 17ms常规波动区间,不足以说明新架构更快
鸿蒙极端页(1680 个 label)的 host 布局耗时17.826s0.694s快约 26 倍platform 层与通信两版持平(5.544s / 5.076s、0.283s / 0.273s),差距全在 host 那一项

Android 的两项相加 142ms,正是文档结论「慢了 140ms 左右」的来源;但同一份文档第一张表算出的差值是 78ms,两张表口径没对齐(见待核实)。

鸿蒙极端页那份还拆了 platform 层:json 解析稳定在 0.8 秒左右、操作视图不稳定、动画平均 1.5 秒——这些新旧一样,迁移碰不到。快出来的 17 秒不是新架构省出来的,是旧架构那一版 host 布局实现太慢。

图 2:三组实测的差值方向与归因
图 2:三组实测的差值方向与归因

四、三个执行决定:顺序、载体、开关

顺序改了三回。

出处主张
规划正文先在 Android 上跑通并验证,再依次尝试 iOS 与鸿蒙
《部分规划调整-1》host 迁移先搞到鸿蒙上,验证问题后再推 Android 与 iOS
《部分规划调整-2》新旧 host 与全新 yoga 一起上,这一次叫「方案二」

而实际上线是依次上的,两份上线记录里同样把「依次上」称为方案二。同一个编号在两处指代相反(见待核实)。

载体是量级挑出来的,不是「挑个低流量」这么简单。 《部分规划调整-2》把候选 App 的日均量级列成了表:

App日均量级判断
美团49 万C 端量太大,风险高,不适合第一站
外卖8.8 万同上
点评3.35 万选中
外卖商家端1B 端量太低,跑不出问题、验证不到
快驴合作商0.3同上
小象 / 骑手 / 众包未知 / 未上线—

原话是「B 端 app 量级太低了,没法验证,C 端诸如美团和外卖量级较大,不太适合」。这与 Yoga 上线选外卖商家端 B 端的口径正好相反——那边只换布局引擎、风险低,量越小越安全;这边改的是架构主干、需要能暴露问题,量太小等于没验证。同一句「选低流量载体」,在两个项目里指向相反的答案。

开关决定了发布粒度。

改动开关出问题怎么办
yoga 升级无white list 置空,强制降级到 i 版收银台
host 新架构horn 开关随时退回旧架构

上线记录据此算过一笔风险账:yoga 升级「页面不可用的概率最大预估为 0.01%,出问题到修复问题的时间最长预估为 8 天」,对应约 64 单。另有两条工程约定:新旧 host 不合入主分支(保主分支稳定性),两个开关都要杀 App 重启才生效。

图 3:排期的三次改动、落地时间线与载体量级
图 3:排期的三次改动、落地时间线与载体量级

五、验收:判据是「与旧架构一致」

迁移类改动的验收基线是行为等价。自测用例整份是游乐场全流程回归(UI 展示、桥、组件属性、RTL、动画、离线包),而大量条目的结论写的是「可忽略,与旧架构保持一致」——纵向滚动的最大值不对、点击返回会退出、某属性无变化,只要旧架构也一样,就不算问题。真正的修复只有 5 条:

问题处置
全局注册视图与局部注册视图不展示修复
图片 blurRadius 失效,onloadstart 无回调修复
contentoffset 无效修复
补 text 与 input 缺失属性修复
桥问题不需要修复,保持和旧架构一样

最后一条最能说明这套判据:新架构发现问题,旧架构同样如此,于是判「不需要修复」。这与前面那份复盘里「对齐的是 RN 的语义而非实现细节」是两种验收——那是对齐外部标准,这是保持自身一致,两类改动不能共用一套判据。迁移类改动若按理想效果逐条判,上面那一大批「保持一致」的正常表现都会被记成问题。

has_new_layout 分析是这套判据下一个很典型的例子:新旧架构对同一份页面算出「哪些节点需要重排」的结论不同,旧架构多出一个节点(第 365 号 RawText)。作者逐节点比对两份变更列表,定位到旧架构里该节点的 cur_layout_height 是 NaN、last_layout_height 是 0,比较结果为假于是判成了「变化了」。这是旧实现的判断缺陷被迁移过程暴露出来的,不是新架构的错。

上线数据方面,两次上线的放量节奏都是 10% → 30% → 50% 递进,埋点按 useNewArchitecture 分组对照。以 host 新架构那批为例,新老两组几乎重合:

日期指标新架构旧架构
2026-01-05抵达率99.865%99.9%
2026-01-05recce_run_tp50859861

真实收银台页面上,这次迁移没有带来可观测的性能差异——这正与游乐场极端页的 26 倍形成对照:日常页面的规模远不到能体现布局差异的量级。

图 4:验收这一环:整份回归大半判「与旧架构一致」,线上则看不到差异
图 4:验收这一环:整份回归大半判「与旧架构一致」,线上则看不到差异

六、可以带走的五条

  1. 理论收益要减掉新增成本才是净收益。 省一次跨语言调用是收益,多一次数据解析是成本,两笔要在同一张账上算。方案把第一笔写进正文、第二笔写进方案细节、性能一节写「暂定」,这是最容易漏掉的地方。
  2. 用性能论证架构改造之前,先问对照组是哪个实现。 收益大小取决于被替换的旧实现有多差,换一个端就会翻转。真正稳的决策依据是那些测不出来的:代码复用、架构自由度。
  3. 「选低流量载体」要配一个下限。 够不够暴露问题,比低不低更重要。改引擎可以选日均个位数的 B 端,改架构主干就不行。
  4. 能不能回滚,决定要不要拆开发布。 有开关的改动可以带着风险上,没开关的改动就得单独安排、留出更长的观察期。这次两件事因此被拆成两次上线。
  5. 迁移类改动的验收基线是「等价」,不是「更好」。 能力补齐是对齐外部标准(RN 的语义),迁移是保持自身一致(与旧架构行为相同)。判据混用会把大量「和旧架构一样」的正常表现记成缺陷。
图 5:三处判断口径值得换一下,以及回滚能力与发布粒度的关系
图 5:三处判断口径值得换一下,以及回滚能力与发布粒度的关系

七、还差的与待核实

事项问题
Android 差值三个口径结论写「慢了 140ms 左右」(=host +72ms 与 platform +70ms 之和),启动耗时表算出 78ms(340.8 对 418.4),点击按钮到上屏那张表算出 121ms(401 对 522);三个数没有说明分别对应哪组数据
数据质量的通病recce_run_tp999 在 8191、16383、32767、60408 之间跳,属样本不足的典型表现,无样本量说明(与 Yoga 上线数据同一个问题);两份上线记录里「结论:」后面都是空的,业务侧指标 host 这次没有对应结论
副本没有声明正本两份同名近似的规划正文逐节相同、只有排期表不同,读者无法从文档本身判断该看哪份;《布局计算迁移 Benchmark》与《安卓游乐场新旧架构 - benchmark 测试》内容重叠,同样是两份
排期表状态没回填现行版最后一格停在「5. 鸿蒙上线验证 进行中」,而实际上线分别在 2025-12 与 2026-01 完成;「调研 host 层闭环文本布局计算的可行性」与「尝试在 Android 上进行 taffy 布局计算框架替换」两格始终是「待开始」,都没有结论或触发条件
「方案二」指代相反《部分规划调整-2》里方案二=两件事一起上,两份上线记录里方案二=两件事依次上;直接引用编号会读错
「三端统一复用」只落地一端规划的首要目标含三端统一复用,实际完成的上线是鸿蒙点评,Android 与 iOS 侧的迁移复用没有找到对应记录

附:读了什么

材料说明
规划两份同源副本《Recce-Host 布局逻辑迁移规划》(2025-07-29 建,挂《03-Host》树下,同日后未再更新)与《Recce 布局逻辑迁移规划》(2025-01-14 建、2025-12-24 末次编辑)。两份正文逐节相同,只有第 5 节排期表不同——后者更新更晚,是现行版。读这份材料必须同时看两份,否则会拿 7 月的进度当现状
它的 6 份子文档《Recce-Host 布局计算逻辑技术方案》(技术方案)、《部分规划调整-1》《部分规划调整-2》(调整-1 / 调整-2)、《关于新旧架构使用不同 has_new_layout 方法结果分析》(has_new_layout 分析)、《安卓游乐场新旧架构 - benchmark 测试》与《鸿蒙游乐场新旧架构 - benchmark 测试》(Android / 鸿蒙 benchmark);另有一份内容完全相同的《布局计算迁移 Benchmark》独立文档
外围印证《Recce-鸿蒙布局计算迁移 自测用例和问题修复》(自测用例)、《鸿蒙点评 11.51.0 上线 recce 1.30 版本【yoga 升级】(已完成)》与《鸿蒙点评 11.55.0 上线 recce 1.30 版本【host 新架构】(已完成)》(两次上线记录)

← 返回工作实践