Recce 渲染规划两年复盘
工作实践约 33 分钟
核实日期:2026-10-13。所有材料均在同日通过学城 CLI 直读原文核对,未引用二手转述。
写在开头:这两年真正长出来的是什么
读完两年规划与三十余份子文档,最值得带走的不是补齐了多少属性,而是这个团队两次给自己划边界,而第二次划的方式变了。
第一次,把模糊的问题变成可数的清单。 25 规划的起点是一句抱怨——「属性支持度不够,业务临时来要会排期紧张」——这句话里没有一个可执行项。它的落点却是两个都算过钱的方案:按业务方代码反推,缺 24 项、约 144PD;直接对齐 RN 全集,缺 178 项、600PD。选了前者,并把没选的那个留在表里。从「不够用」到「缺 24 项」,是整件事由模糊变清晰的临界点。
这一步的手法值得单独记下来:当清单大到做不完时,不是更努力地做完它,而是换一个更锋利的参照物,把清单重新切一遍。 178 项是按「RN 文档列了什么」切的,24 项是按「业务方代码真的用了什么」切的;同一个问题,换参照物,规模差七倍。同一个动作在 26 规划里又出现一次——新增一列「RN 实现层」,把「RN 列了这个属性」与「这个属性需要原生实现」拆开,Image 专表里 14 个未支持项因此全部判「不需要支持」。
第二次,承认清单有尽头。 26 规划把口径从「补够用」改成「以 RN 为基线,补其短板,探其边界」,目标写成 157 项、各组件从 50%~62% 提到 100%。但真正的方法论进步不在这句口号里,而在于它同时承认:补完清单不等于没有问题了。背景重构那份需求结尾写得很直接:
这些问题是已知的,当然还有很多未知的问题,如何主动识别并解决这些问题才是更重要的。
这句话把目标从「清单清零」换成了「建一套能持续发现问题的机制」。前者有终点,后者没有。
这两件事不是二选一,是同一件事的先后。 不先把边界划清楚,就没有「已知清单」这个基数,也就无法定义什么是「未知」,顺序不能颠倒。反过来,只做第一步会掉进一个陷阱:把清单当成全部,清单之外的问题只能等 QA 来撞——背景重构那 14 条里,9 条是 QA 或开发在真实业务里撞出来才登记的,没有一条是靠属性清单推出来的。
而「主动识别」的落点,材料里也已经给出了样板,只是被放进了暂停状态。差异扫描把 Recce 与 RN 的 Android 源码逐文件对读,一次捞出 14 条高置信 bug——其中 snapToAlignment 在属性表上是绿的(值收得到、三端都支持),但它在 flingAndSnap 里根本没参与计算,三种对齐方式全部失效。这类问题盯着 RN 的属性文档看一辈子也发现不了,因为它换的不是努力程度,是对照面:从「RN 的文档」换成了「RN 的源码」。
把两年合起来,可以带走一句话:
清单失控时,换参照物;清单做完时,换对照面。
前半句解决「不知道要做多少」,后半句解决「不知道还差多少」。
读了什么
两期规划正文:《Recce Native 渲染规划(2025)》(下称 25 规划,基线 Recce 1.25 / RN 0.72)、《Recce Native 渲染规划(2026)》(下称 26 规划,子文档已按 RN 0.86 / Recce 1.34)。
- 25 侧 22 份子文档:《Yoga 引入方案调研》(选型调研)、《引入3.2.1版本 Yoga 需求和方案》(Yoga 方案)、《Recce 布局计算引擎(Yoga)升级 - B端上线》(上线记录)、《Recce - RN Changelog 同步机制》(Changelog 机制)、《其他框架的业务属性调研情况》(业务方调研)、《Recce VS RN 缺失属性对齐》(属性对齐总表)、三端逐组件的 0.72 对齐进展、1.29 / 1.30 / 1.32 三期技术方案。
- 26 侧 6 份子文档:《1.3x Recce native 背景逻辑重构需求》(背景重构,下含《iOS 文本继承关系》)、《1.32 Image缺失能力完善(二期)》(Image 二期,下含《Recce SVG技术方案》即 SVG 方案、《自测用例》)、《组件渲染属性对齐RN0.86版本》(0.86 总表)。
- 2026 年落地侧:《Recce 1.35版本需求》(1.35 需求)及其下 7 份组件 / 样式专表(View、ScrollView、Image、Shadow、Label、Layout、TextInput,统称组件专表)、《Recce 1.34 版本需求》、《Recce 与 React Native Android 组件实现差异扫描》(差异扫描)、《【iOS】1.35 渲染属性对齐》;另引《05-客户诉求池》(诉求池,密级,读不到原文)。
词表
- 补齐 / 对齐:补齐=新增 Recce 不支持的属性;对齐=属性已支持但行为与 RN 不一致,把它改过来。成本结构与验收方式完全不同,两年里分在两张表里排期。
- 口径一 / 口径二:25 规划里对「最终要支持多少属性」的两种定义。口径一按业务方代码反推(缺 24 项),口径二直接对齐 RN 全集(缺 178 项)。
- native prop / JS 层属性:RN 属性里一部分由原生侧实现,一部分只在 JS 层处理(吸顶、下拉刷新、键盘收起策略都是这一类)。只有前者才需要 Recce 原生侧补。
- 放量(灰度):按 uuid 比例分批放开新能力,观察一档稳定后再进下一档。
- 存量异常归因:判断线上异常是新版本引入还是旧版本本来就有,避免把存量问题算到新改动头上。
一、两年的问题定义变了
25 规划的起点是「属性支持度不够,业务临时来要会排期紧张,且影响 Recce 其他渲染工作进度」,落成三条目标:集中补齐新增属性、已有属性与 RN 对齐、制定 RN Changelog Fixed 同步机制。
26 规划把起点换成一句自问自答:
Q:Recce 渲染要做成什么样子?对比现在缺少了哪些能力?怎么去更好地实现这些能力? A:如果要完全对标 Web 那样的渲染能力,恐怕不是很现实……以 RN 为基线,补其短板,探其边界。即不追求 Web 全集,追求在 Native 约束下的最优解。后续进行自绘制开发时,再去打破这个约束。
从「补够用的属性」到「承认边界、只求 Native 约束下的最优解」,是这两年最大的一次口径变化。它有两个直接后果:补齐从「按业务代码反推、够用就行」改成「按需全部支持完」(157 项,各组件从 50%~62% 提到 100%);「已有属性对齐」被升级成「三端渲染一致性」,验收对象从 RN 换成 iOS / Android / 鸿蒙三端。
二、逐个方向走了一遍
2.1 基础属性补齐:口径从「业务反推」走到「按需全量」
这是 25 规划的主线,也是唯一一个两年都在做的方向。
| 组件 | 2025 现状(RN 0.72 全集) | 2025 目标(口径一) | 2026 现状(仅 native prop) | 2026 目标 | 26 规划标的状态 |
|---|---|---|---|---|---|
| 通用布局 | 93%(52/56) | 100%(56/56) | 100%(56/56) | — | ✅ |
| 通用阴影 | 0%(0/4) | 100%(4/4) | 100%(4/4) | — | ✅ |
| ScrollView | 44%(27/61) | 52%(32/61) | 52%(38/59) | 80%(49/59) | 🚧 |
| Image | 48%(24/50) | 58%(29/50) | 53%(16/30) | 53%(16/30) | ✅ |
| Label | 46%(31/69) | 50%(34/69) | 40%(17/42) | 88%(37/42) | 🚧 |
| View | 48%(46/94) | 51%(48/94) | 未填 | 未填 | 🚧 |
| Input | 53%(41/67) | 62%(42/67) | 未填 | 未填 | 🚧 |
25 规划给两个口径都算了成本:口径一缺 24 项、约 144PD;口径二缺 178 项、600PD、平均 200PD/端。选了口径一,理由(贴近具体业务、工作量小)与代价(不能百分百保证未来需要某些奇特属性)都写在正文里。优先级按业务紧急程度切,近期要用的通用布局与阴影定 P0、其余 P1,三端 owner 明确到人。
分母这件事两年里都没定死,所以前后不能横着比。
比分母更值钱的,是 26 规划新增的那一列「RN 实现层」——它把「RN 文档里列了这个属性」和「这个属性需要 native 实现」拆开了,于是大量条目判「否」,而不是继续往 native 侧堆工作量:
- Image 专表 30 项里未支持的 14 项全部判「不需要支持」:
defaultSource、loadingIndicatorSource、onProgress是「属性鸡肋」,src是「source 已有」,crossOrigin、referrerPolicy可以走 headers,resizeMethod一族因为「recce 用 picasso、rn 用 fresco,两套图片机制」。 - ScrollView 专表把 11 个非 native prop 逐条写了 JS 层怎么实现:
stickyHeaderIndices是遍历 children 把子节点包成ScrollViewStickyHeader;refreshControl在 iOS 是当子节点放进去、在 Android 是包裹 ScrollView;onContentSizeChange是转onLayout出来的。
这一列的价值超过补齐本身:它把「对齐 RN」从一个无底洞变成了一个有边界的清单,也是 2.2 里那些「不采纳」结论的方法基础。
2026 年这条线换了组织形式——不再是规划里的一张总表,而是每个组件 / 样式一份专表,标题带状态前缀,统一挂在 1.35 需求下,共 7 份(View 那份含 Props 与 Style Props 两张表)。实际状态是 Image、Shadow 收口,View 与 ScrollView 今年也已经对齐,但这两份标题至今仍写【对齐中】。Label、Layout、TextInput 标【暂停】,其中 Label 那份只有标题、没有结论。
专表比总表更有用的地方,是它把「不支持」拆成了性质不同的几类,而这几类的解法完全不一样:
- 上游压根不是 native prop——判否的主要依据,也是省下工作量最多的一类。
aria-*全系 11 项判「没必要,有等价属性」,collapsable、testID、id、nativeID判「框架已有能力支持」。 - 目标平台没这个能力——View 的 11 项无障碍属性全部判否,理由都是同一条「鸿蒙不支持无障碍」。这类不是「不做」,是做了也没有落点。
- 依赖别的工作——
hitSlop、pointerEvents、focusable、tabIndex与 10 个onResponder*都判「需要,但依赖触摸事件重构,本期不支持」。这解释了 1.35 里为什么触摸事件重构排 P0、属性对齐只排 P1——属性对齐有一截排在触摸事件重构后面。 - 剩下才是真工作量——View 侧 23+15 项、ScrollView 侧 10 项 native 加 10 项待 recce-ui 配合、TextInput 侧 33 项、Layout 侧 20 项。
这批专表也顺带补上了 26 规划总表里 View、Input 两行留空的问题。
2.2 已有属性对齐:逐属性 diff,对的是 RN 的语义而非实现细节
25 规划把这件事排进了月表:2 月 View 与 Image、3 月 Input 与 Label、4 月 ScrollView 与 HorizontalScrollView,基线 RN 0.72.0。做法是逐属性 diff,每条给「采纳 / 不采纳」加影响面,不采纳的也给理由。判例最能说明这套方法:
| 属性 | 差异 | 结论 |
|---|---|---|
caretHidden / keyboardType | 新版修了小米 Android 10 上的 crash | 机型兼容性修复,采纳 |
secureTextEntry | value 为 true 时只清 TYPE_TEXT_VARIATION_VISIBLE_PASSWORD 一个标志位,而不是清掉全部 | 功能优化,采纳 |
fontWeight | 新版用 TypefaceStyle 支持 100–900 字重,Recce 只有 bold 与 normal | 重要能力,需要支持 |
textDecorationLine | 新版支持 underline line-through 组合值 | 重要能力,需要支持 |
cursorColor | 采纳后会导致 Android 8.1 以下设备光标异常 | 不采纳 |
ellipsizeMode / textTransform | 新版加了兜底默认值;Recce 写不存在的值上层直接编译报错 | 不采纳,保持现状 |
adjustsFontSizeToFit | 改动量大,且 Recce 本来就没真正实现 | 暂时不采纳 |
注意后面几条不采纳的理由:都不是「做不了」,而是「采纳后比现在差」或「Recce 的编译期约束已经把它挡在前面了」。对齐的目标是 RN 的语义,不是 RN 的实现细节——这一点两年材料里没被显式写出来,但所有判例都按这个口径判,值得补成一条原则。
第三种做法:直接对源码。 属性清单那条路是在文档层面做对照,2026 年多了一条更硬的路——差异扫描把 Recce 的 android/recce/views 与 RN 的 ReactAndroid/.../views 逐文件对读,只收高置信的行为差异,一次得到 14 条,4 条已修、10 条待修。它回答的是「做得对不对」,而属性矩阵只回答「有没有」:snapToAlignment 在属性表里是绿的(值收得到、三端都支持),但它在 flingAndSnap 里根本没参与计算,pagingEnabled 下 start / center / end 三种对齐全部退化成普通分页。这种问题盯着 RN 的属性文档看一辈子也发现不了。
它还留了一条别处没写过的口径:第 10 条 maxLength 追加 LengthFilter 时数组下标写错、会抛 ArrayIndexOutOfBoundsException,作者注明「react-native-main 同位置仍能看到类似写法,因此这条不是 Recce 相对 RN main 的差异」,但仍建议顺手修。也就是说这类扫描只能识别「与对照物不同」,识别不了「两边都错」。
25 规划的最后一条目标是 Changelog 机制。背景写得很直白:Platform 层的实现对标的是 RN 0.63.x,而 RN 平均 2~3 个月发一个大版本,那两个已暴露的问题在 0.78.0 就修了、Recce 没跟,「实际上可能还有很多新版本中已经解决但我们未能察觉的潜在问题」。机制只审 Changelog 的 Fixed 部分,重点是 crash 相关的稳定性修复与组件样式渲染修复;节奏给了两套,选了简单那套(从 0.64.0 起每个迭代审 3 个大版本、约 6 个月追上),双线并行那套 5 个月能追上但被否,理由是「跟进压力较大、可能出现重复更新」。
2.3 布局引擎:Yoga 3.2.1,唯一跑完全程的一件
这是 25 规划里动作最完整的一件,也是唯一把「调研 → 选型 → 方案 → 集成 → 分档放量 → 数据验收 → 回滚预案」跑完的。
选型先把四个候选(yoga / taffy / blink / stylo)的工程规模与 issue 数摊开,再逐项对照属性支持,结论是「核心属性支持程度 taffy 和 yoga 持平,属性支持的值 taffy 比 yoga 多」,但 taffy 当时不支持 position: static 与 RTL。三个方案里否掉「新增组件引入」(要过平台审批),选定「融合进 Recce 已有组件」,把「换成 Taffy」留作长期备选,原话是「这个事情可以等到布局计算迁移之后」。
落地上有几个细节值得记:三端各自引入 release/3.2.1 分支;Android 必须改包名(yoga 编译时用的包名是 com.facebook.yoga,mrn:yoga 也是,不改会冲突,改成 com.meituan.android.recce.yoga);so 引入选「脚本拉仓库编译后取中间产物」而不是「把文件复制进工程」,理由是更新成本低、源码分离,代价是构建时间长;先保留 mrn:yoga 依赖做兜底;horn 开关默认 false,按 bundleName 白名单放量;双端所有埋点加通用字段 use_new_yoga。
上线载体选外卖商家端 7.16——C / Keeta 对稳定性与性能要求都高、不好做实验,所以找流量小的 B 端做验证。放量与观测结果见图 5。两个需要留意的数字口径:包体增量在两年里出现过两种说法(见待核实第 2 条);benchmark 只在华为 Mate 30 上跑过,结论是「耗时上没有明显差距」,样本很薄,不能当性能结论用。
2.4 高级表现力:2026 新开的方向,P0 三项已落地
25 规划里这件事还不成方向,只是通用阴影从 0%(0/4)补到 100%(4/4),BoxShadow 挂在 1.32 排期上标「待完成」。26 规划把它单列为一条,理由是「全球化拉高 UI 水平」。
七项能力的支持情况:
其中 SVG 的选型过程值得单独看,五个方案的取舍依据很清楚:
| 方案 | 优点 | 缺点 | 结果 |
|---|---|---|---|
| RN-SVG | 三端一致性高,解析逻辑集中在 recce-ui | 总体开发成本高;子标签多时 native 视图多,性能存疑 | 未选 |
| androidsvg 纯原生 | 性能好(渲染出来是一个视图);包体可控 | 三端一致性不是完全一致;维护成本较高 | 最终采用 |
| rust-resvg | 三端像素级一致;三端开发成本低 | 包体预估 +2.5MB;复杂 svg 下开销直线飙升 | 初选,后放弃 |
| rust 解析 + native 渲染 | — | 三端开发成本高;包体压力 | 未选 |
| thorvg | 三端像素级一致;性能高 | 三端开发成本较高;包体约 +600KB | 备选 |
benchmark 数据(Android):复杂图 thorvg 52ms、native 70ms、rust >1000ms 且无法稳定加载;包体 native 最小 < thorvg 约 600KB < rust(优化 feature 后 Android release 增量 2.0MB,再去掉文本支持降到 1.0MB)。最终结论是从「像素级一致」退到了「性能与包体可控」。
source 上有一条硬约束:只支持 utf8 与 base64 两种带前缀的字符串,不支持本地文件和远程图片;recce-ui 的宽高与其他样式都不作用到 svg 上。两条都是被业务实际用法顶出来的边界,写清楚比不写强。
BoxShadow 的调研侧做得比较足:对齐 RN 0.83,把 Recce 的 elevation 方案、MRN 的 shadow* 方案、社区的 @mrn/react-native-shadow-view、Web CSS 的 box-shadow 摆在一起对照,兼容性写了 Android 9+(外阴影)/ 10+(内阴影)、iOS 13+,性能风险写了「低端 Android 设备上帧率可能从 60 FPS 下降到 15-20 FPS」。但「三、方案」的三端小节是空的。
2.5 背景与边框逻辑重构:三端一致性从口号变成了清单
26 侧真正的工程量在这里,但它在规划正文里没有独立条目,藏在子文档里。两个动因是「Recce 需要支持 BoxShadow」和「Recce 目前的背景渲染存在很多与 RN 不一致的问题,其中有开发梳理发现的,也有 QA 测试发现的」,一口气列了 14 条:
清单里两类特别值得记:一是同名不同义,比如 borderStyle 在非图片场景下,Recce-Android 是「有圆角时视图被 border 挤、没圆角时 border 盖在视图上」,而 RN 不管有没有圆角都是盖在视图上;到了图片场景,Android / iOS 是 border 盖在图上、鸿蒙是视图被 border 挤,而 RN 是被挤。二是属性互相干扰,比如图片设了圆角时 resizeMode 失效。
结尾那句话是这两年材料里方法论价值最高的一句:
这些问题是已知的,当然还有很多未知的问题,如何主动识别并解决这些问题才是更重要的。
它和 26 规划关键结果里的「借助 AI 建立自动化测试,扩充测试用例,充分覆盖所有属性,提前发现潜在的不一致性问题」是同一件事的两面。到核实时,关键结果那一侧仍然只停在纸面上(用例从哪来、判定标准是什么都没写),但主动识别已经有一份样板做出来了,就是 2.2 里那份源码级差异扫描。
同一批工作还有个连带产物:为了支持 label 的 border 能力,iOS 侧把 RECTextView 的继承链从 UIView 改成 RECView,文字绘制交给新增的 RECTextContentView,并给出 15 条影响面清单(P0 四条:纯文字渲染、padding 生效、嵌套 Text、onClick 点击命中)。这类改动的影响面写法是这两年文档质量最高的一处。
2.6 版本维度:1.34 与 1.35 这两期在做什么
规划是按方向写的,实际落地是按版本排的,两套口径之间没有总表。把两期需求表并起来看,2026 年后半年的形状比较清楚:
| 版本 | 主要任务 | 与属性对齐的关系 |
|---|---|---|
| 1.34 | touch 事件回调支持指针坐标(三端)、View 背景重构(Android 重构,iOS 与鸿蒙修 bug)、支持 BoxShadow(三端)、图片 source 属性重构、iOS 图片迁移 SD、差分包、样式热重载 | BoxShadow 与背景重构是「已支持属性对齐」的地基;Image 专表在这一期收口 |
| 1.35 | 触摸事件重构(P0)、Android 17 适配(P0)、Android yoga 加载方式优化(P0)、View 与 ScrollView 属性对齐(P1)、差异扫描(P2,暂停) | 属性对齐这一批集中在这一期,且被排在触摸事件重构之后 |
这张表也解释了一个读表时会困惑的点:属性对齐在需求表里只是 P1,P0 让给了触摸事件重构与平台适配。原因就在 2.1 里那 14 个 onResponder* 与 hitSlop、pointerEvents 一类属性——它们不是「没做」,是必须等触摸事件重构落地才能做。1.35 需求表的行序是有依赖依据的,只是这个依据没写在表里,得翻到专表才看得见。
三、值得抄走的七个动作
- 两个口径都算成本再选,并把没选的那个留在表里。 144PD 与 600PD 摆在一起,选了便宜的,理由与代价都写在正文。决策依据可复查——这是规划类文档里最先丢的东西。
- 需求是扫业务方代码扫出来的,不是拍出来的。 业务方调研逐个给了调研对象与搜索方式(MRN 侧搜
StyleSheet.create、remStyleSheet、.scss,MachPro 侧搜index.css),每处配截图与代码包附件。清单有出处,别人能复核。 - 高风险改动选低流量载体,放量有明确节奏。 Yoga 不在 C / Keeta 上做实验,改用外卖商家端 7.16,1% → 30% → 50% → 80% → 全量,每档给观察期与结论;第一档发现「叠加 App 自带灰度后基本没量」当天就调档,这个反应比节奏本身更有价值。
- 数据三件套:埋点带维度、指标先定口径、存量先归因。 双端所有事件加
use_new_yoga字段,同一天就能比新旧,不受大盘波动影响;技术指标与业务指标的 SQL、关联键(trade_no)、过滤条件(isDevMode、isRebuild)都写进文档,换个人跑得出的是一组数;subview_empty与offline_downgrade两条异常都先确认是存量、给了排除依据,没有算到新改动头上。 - 肯写「不采纳」与「暂时不实现」,也肯承认边界。 单边
borderStyle明确判「暂时不需要支持,保证三端一致即可」;26 规划直接写明高性能列表「没有原生实现,只有 js 侧封装,这块 React Native 是个短板」,蒙层借鉴masked-view、手势借鉴gesture-handler。只列「要做什么」的规划没法判断边界,这份能。 - 目标变得可度量了。 26 规划的 KR 写了具体数字与分期:高级表现力 0.7 达 75%(6/8)、1.0 达 100%(8/8),核心组件 0.7 达 70%、1.0 达 100%。比 25 规划的「完成补齐」可考核得多。
- 方案与用例成对交付。 Yoga 有集成测试计划、测试账号、测试重点;SVG 有《自测用例》8 组 source × 存在性组合;iOS 文本继承有 15 条影响面清单。这些是让改动可验收的前提。
四、还能更好的地方
1. 分母要定死,并且和 RN 版本一起冻结。 这是本文最想指出的一条。同一个组件在两年里出现过三套分母(Image 从 50 到 30、Label 从 69 到 42、ScrollView 从 61 到专表的 59、而 26 规划总表那处又写 62),叠了「RN 基线从 0.72 升到 0.86」和「是否剔除 JS 层属性」两个变量,外界无法判断进度是真涨还是分母换了。更麻烦的是比例列看起来是手写的、没和分数联动:25 规划里 Input 写「53%(41/67)」,41/67 是 61.2%;Label 写「46%(31/69)」,是 44.9%;26 规划里 ScrollView 写「52%(38/59)」,是 64.4%。三处比例与分数对不上。建议把属性矩阵做成四列——属性 × 冻结的 RN 版本 × 三端现状 × 是否 native prop——并单独记一列「因 RN 升级新增 / 删除的属性数」,让分子分母都有解释。
2. 26 规划的 157 项要给出算法和成本。 25 规划给了 PD,26 规划只给完成率。0.7 达 70%、1.0 达 100% 这两个 KR 没有人力口径,就判断不了是否排得下,也没法在中期判断要不要调目标。
3. 三端差异清单要从一次性文档升格成常驻资产。 现在它躺在背景重构那份需求里,差异扫描那 14 条又是一份新的一次性清单。建议合成一份常驻表:属性 × 端 × 现状 × 期望 × 发现来源(业务反馈 / 属性矩阵 / 源码扫描)× 状态,并把它当作主指标(差异数)、完成率当辅指标——差异数不会因为分母变化而失真,完成率会。
4. 「借助 AI 建自动化测试」要落成第一批可执行用例,但性价比最高的第一步不是搭框架。 素材已经有三批:SVG 方案的 5 项用例(base64 / utf8 加载与回调、固定宽高、自适应宽高、resizeMode、错误加载)、《自测用例》的 8 组 source × 存在性组合、7 份专表里判「需支持」的条目(每一条都是一句可断言的行为)。建议先落两级判据——语义断言(回调触发次数与顺序、默认值、属性是否生效)加截图 diff,不要一上来追像素级,否则低端机与字体差异会淹掉真实缺陷。但如果只算一步,应该是把差异扫描从暂停里放出来:它不需要跑设备、不需要判定基线,只要对读源码,10 条待修里每条都写好了风险场景与测试重点。
5. Changelog 同步机制要分层,不能拿一条 6 个月的队列追到底。 从 0.63 追到 0.72 再追到 0.86,说明「每迭代审 3 个大版本」这个速度跟不上上游。建议把 Fixed 里的 crash 与渲染两类定为必须当期跟,其余按季度批量扫;否则永远在追身位,而这两类恰恰是线上最贵的。
6. 对齐基线的切换与备选方案都要带触发条件。 25 规划定 RN 0.72 的理由写得很清楚(「该版本是鸿蒙所能支持的最新版本」),26 规划的子文档已经在按 0.86 对齐,但两次切换只写了目标版本,没写「为什么现在可以升」和「鸿蒙跟不跟」;Taffy 那张完整的 Yoga vs Taffy 对照也没写什么情况下值得换。建议把基线当决策记录来写,给备选方案一个可观察的触发条件(例如「需要 grid 布局的业务方达到 N 个」或「RN 侧 grid 提案落地」),否则这张表每版重抄一遍而不产生决策。
7. 状态标签要从标题里挪出来,另设一张总表。 「1.29 补 View/Image/ScrollView」「1.30 补 Input/Label」「1.32 BoxShadow」「1.34 对齐 RN 0.86」现在散在各文档标题里,两年后的读者要从几十份文档里拼。一张版本 × 方向 × 状态的总表就能省掉这件事,也是上面第 1 条那张属性矩阵的天然入口。附带一个真实踩到的例子:View 与 ScrollView 的属性对齐今年已经完成,两份专表标题却还写着【对齐中】——状态写进标题就没有人负责更新它,本文第一次成稿正是照标题判的,把已完成的两项读成了在途。
8. 两个小约定:高百分位要标样本量,留空要标「待补」。 Yoga 上线数据里 recce_run_tp999 在 1151 / 4053 / 8191 / 10239 之间跳,是样本不足的表现,建议这类数字直接标「样本不足,不参考」,或把长周期性能结论交给 C 端小流量、崩溃类结论留在 B 端;BoxShadow 的「三、方案」与背景重构的「3. 具体规划」都留空了,留空容易被后来人读成「已评估、无问题」。
五、待核实
- 成本对不上 10PD,排期表没写年份。 25 规划表里口径一写「总成本 144PD」,注释拆出来是研发 109PD 加测试 25PD=134PD。分月表表头只有「1月~6月」,而 Yoga 实际是 2025-07 随 1.28 上线的,与表里「1月完成 yoga 引入」的对应关系无法从文档确认。
- Yoga 包体增量有两个口径。 选型调研与上线记录把 Android「489.52KB / 压缩后 194KB」写成增加量;Yoga 方案的包体表把这两行标成「老版本 yoga 的体积」,新版本是「428.52KB / 168.4KB」。
- 26 规划的 157 项是怎么加出来的。 25 规划的全量口径是 178 项,两者差 21 项,中间 RN 基线还升过级,判断不了这个差额是「按需裁剪」还是「口径重整」。View 与 Input 原来留空的两行现在由专表补上了(View Props 61 项、Style Props 43 项,TextInput 68 项),但两处口径是否一致没交代。
- 高级表现力的分母对不上,统计维度也不全。 表里列了 7 项能力,KR 写的是「6/8」与「8/8」;「Recce 是否支持」只有一列,没分端也没写落地版本;复杂手势、高级动画、高性能列表三项只有优先级,没有版本与跟进人。
- 专表自身有几处对不上。 TextInput 同节既写「3 项没必要 / 33 项需支持」又写「本期支持 31 / 5 项没必要」,差 2 项;ScrollView 专表写 59 项、26 规划总表写 62 项,分子分母都取自专表而总数列来源不明;Layout 专表没给总数(只写「未支持的 21 个中支持 20 个」),算不出完成率。
- 对齐进展那份文档正文是空的。 《Recce现有属性对齐0.72版本 RN 进展》只有标题、下挂三份 Android 子文档,iOS 与鸿蒙侧的对应结论没找到。
- 业务调研原文读不到。 26 规划引用的《业务调研》是密级文档,返回「当前内容含高密文档,需在安全屋环境中访问」。文中的业务诉求引用来自 26 规划转录的诉求分布图(基础属性 7、手势能力 3、文本渐变 1、高级动画 1、canvas 1、复杂列表 1,共 14 条)。
- 平台层对标版本有两说。 Changelog 机制写「Platform 层实现对标的是 RN 一个较老的版本 - 0.63.x」,25 规划写属性对齐基线是 0.72.0。语境不同但文档没点明,容易被读成矛盾。
- 状态标签与标题不同步。 View 与 ScrollView 的属性对齐今年已完成,两份专表标题仍写【对齐中】,判断状态的唯一依据是标题,容易读错。
- Label 专表只有标题。 暂停的原因(缺人力、缺业务需求,还是等别的前置重构)没有记录,后来人只能重新问。