
Relay 2016 上半年技术路线图从团队同步会议看五项核心计划的演进与落地【免费下载链接】relayRelay is a JavaScript framework for building>项目地址: https://gitcode.com/gh_mirrors/relay29/relay导读本文基于仓库中保留的 2016-03-14 团队同步会议记录还原 Relay 团队在开源初期的 H1 技术规划——包括为慢速设备与弱网打造高性能应用的目标背景、五项重点工程更快的核心、新连接 API、低层 mutation API、规范化响应格式、持久化查询以及开源协作策略。文章以这份会议记录为骨架对照当前仓库中的编译器与运行时源码逐一验证这些 2016 年的计划在今日 Relay 中的实现形态帮助读者理解 Relay 架构演进的历史脉络与关键设计的落点。会议背景这是一份什么样的文档meta/meeting-notes/目录保存了 Relay 团队 2016 年的历次同步会议记录2016-03-14-team-sync.md 是其中之一。会议议程只有两项状态更新Status Updates与H1 计划讨论Discussion about H1 plans。值得说明的是会议记录开头特别注明上周没有同步团队大部分成员远程办公因此这份文档实质上是一次跨周的状态汇总与季度规划讨论。虽然形式上是碎片化的会议纪要但其中的 H1 计划部分包含完整的技术背景与五项明确的工程方向且每一项都能在当前仓库中找到对应的实现这正是本文展开的核心素材。状态更新会议纪要里透露的技术线索会议记录了七位核心成员的状态更新虽然每条只有一两句话但拼合起来可以清晰看到 2016 年初 Relay 团队的关注面React Native 与 Relay 开源版兼容steveluscher同时继续 RelayConnection 相关工作低层 mutation APIRelayGraphQLMutationwincent并同步推进 mutation 文档编写与内部 mutation 的校验开启大列表上的 diff 查询性能问题kassens正在调查为何 diff queries 在大列表场景下变慢持久化查询Persisted queriesyungsters当时正处理日志问题与 Web 侧相关事务跳过空字段skip null fields与复用客户端 IDyuzhi支持 Facebook GraphQL 的空字段跳过特性并修复客户端 ID 复用contextual Relay 与服务端渲染josephsavona已发布 contextual Relay下一步是服务端渲染同时提出 Relay Core /react-relay拆分提案并验证了不做 query tracking性能为正、不保留 paths性能中性的 PoC。这些条目几乎每一条都能在今日仓库中找到延续。例如服务端渲染演化为react-relay中面向 RSC 的 useQueryFromServer.js不做 query tracking / 不保留 paths 的思想与当前运行时以数据 ID 与规范化记录为核心的RelayModernStore设计一脉相承。会议记录的价值不在于字面信息而在于它标记了这些设计决策最早被讨论的时间点。H1 计划背景为任意设备、任意网络构建应用H1 计划的背景部分明确阐述了性能工作的出发点我们与 Relay 的目标之一是让开发者更容易构建在任何设备、任何网络下都能良好运行的应用。会议记录指出Facebook 观察到越来越多用户在移动设备与慢速网络上使用产品典型场景是新兴市场的用户使用 2011 年级别的低端手机year-class 分类体系中的旧机型并接入 2G 级别网络。这些设备与网络带来独特的工程挑战Relay 核心团队因此将改善这些场景下的性能作为主线。这一目标在当前仓库中仍有直接对应仓库根目录保留了 skills/relay-performance/SKILL.md 性能实践指南以及运行时中的 RelayFeatureFlags.js用于按特性开关控制开销较大的能力。可以说2016 年设定的低端设备 弱网性能目标贯穿了 Relay 后续十余年的演进。五大重点工程规划与今日实现对照在标准性能手段profiling、benchmarking之外会议列出了五项高优先级工程。以下逐一展开并结合当前仓库源码说明其落点。1. 更简单、更快的 Relay 核心计划原文是在可能的情况下将非关键特性移动到核心之上的一层以保持开发者体验并获得额外性能。从当前仓库结构看这一策略的直接体现是核心与外围能力的物理分层数据获取核心收敛在 packages/relay-runtime 中其中 RelayModernStore.js、RelayReader.js、RelayResponseNormalizer.js 构成规范化存储 读取的最小闭环与 React 强绑定的容器、Hooks 位于 packages/react-relay/relay-hooks属于核心之上的一层编译器在 2021 年relay-19 发布博客被整体重写为 Rust 实现即 compiler/crates 目录下由relay-compiler、relay-transforms、graphql-*等 crate 构成的工具链进一步印证了核心要快的取向。会议中提到的React Native Relay OSS 兼容也属于这一工程核心保持环境无关才能在 React DOM 与 React Native 之间共享同一套数据层。2. 面向复杂列表视图的全新连接ConnectionAPI会议计划新的顶级连接 API为复杂列表视图优化。这份规划最终沉淀为两层能力运行时连接处理器ConnectionHandler.js 实现了连接字段的默认处理逻辑。其核心update函数第 50 行起会把新拉取的 edge 追加到已有连接末尾并借助__connection_next_edge_index第 41 行为每条新 edge 生成唯一的客户端 ID保证分页追加时记录不冲突Hooks 层分页 APIusePaginationFragment.js 与 useLoadMoreFunction.js 提供声明式的加载更多体验配合getPaginationMetadata/getPaginationVariables见 packages/relay-runtime/util自动维护游标与连接参数。从会议记录中的RelayConnection 工作到今天usePaginationFragment的成熟形态连接 API 是五年规划中落地最完整的一条。3. 新的低层 mutation API减少簿记开销会议指出新的低层 mutation API 旨在帮助减少一些簿记bookkeeping开销。今天对应的实现集中在 packages/relay-runtime/mutationscommitMutation.js 是命令式提交 mutation 的入口applyOptimisticMutation.js 负责乐观更新RelayDeclarativeMutationConfig.js 提供声明式配置如RANGE_ADD、RANGE_DELETE、NODE_DELETE把新增/删除 edge 后如何更新连接这类高频簿记逻辑封装起来避免开发者手写 store 更新代码——其实现中对RANGE_ADD的 parentID 缺失第 173 行与RANGE_DELETE的 connectionKeys 缺失第 317 行都会给出明确告警正是减少簿记负担的具体体现。Hooks 层的 useMutation.js 则把这一 API 接入 React 生命周期完成从 2016 年提案到现代用法的闭环。4. 规范化 GraphQL 响应格式Normalized GraphQL response format在会议中仅有一行但其含义深远服务端响应不应是树状的原始 JSON而应是可按 ID 扁平化归并到 store 的规范化格式。当前仓库中RelayResponseNormalizer.js 负责把响应写入规范化记录RelayExperimentalGraphResponseHandler.js 则是在此基础上的流式/增量处理实验。规范化响应的收益正如会议隐含的目标跨查询复用同一实体、避免重复存储、并支持服务端渲染时把已获取数据接续到客户端——这正与状态更新中下一步是服务端渲染的计划呼应。5. 持久化查询Persisted Queries构建期生成只发送查询 ID会议原文构造期生成查询只向服务器发送查询 ID。这是弱网场景下减少请求体积的关键手段也是当前仓库中实现最完整、可配置项最丰富的计划。配置层relay-compiler的配置结构 project_config.rs 定义了PersistConfig枚举分为两种模式Remote(RemotePersistConfig)通过 POST 请求把文档持久化到远端端点。该结构支持url端点地址、headers附加请求头、concurrency并发上限配置为 0 会直接报错提示见 第 107-113 行、include_query_text是否在持久化文档中包含查询文本以及schema_text参数第 52-100 行——后者用于当持久化端点无法按名称查找 schema 时随请求附带 schema 文本以便校验Local(LocalPersistConfig)把文档持久化到本地 JSON 文件可配置file路径、哈希算法MD5/SHA1/SHA256默认 MD5见 第 116-141 行与include_query_text。实现层持久化器位于 compiler/crates/relay-compiler/src/operation_persister包括本地版 local_persister.rs 与远端版 remote_persister.rs。以本地持久化为例LocalPersister::new第 38-56 行会在文件不存在时从空映射起步、由finalize负责创建文件hash_operation第 58-70 行则按所选算法对操作文本做哈希作为查询 ID 写入映射。这套从配置到实现的完整链路正是会议记录中只发送查询 ID从一句话规划变成生产级能力的过程。开源策略核心改动与社区支持的平衡会议记录的开源部分阐述了 Relay 团队对社区工作的两条原则实现核心改动优先落地能带来新特性或性能收益、且对团队自身与大多数社区用户都有益的改动。记录中给出的示例是开源后不久发布了 React Native 示例应用并落地了服务端渲染的前置工作支持社区在外围发展新特性会议提到的 Relay Core API 提案Relay Core /react-relay拆分正是这一策略的纲领——核心保持精简社区可以在外层自由扩展。从当前仓库看这一分工已成为现实packages/react-relayReact 专用层、packages/relay-runtime环境无关的核心各自独立成包编译器则在 Rust 重写后通过relay-compiler提供稳定的构建期能力见 packages/relay-compiler 的 CLI 入口 cli.js。社区开发者既可以只使用运行时也可以按需组合编译器与持久化配置。结语一份会议记录中的架构演进线索2016 年的这份同步会议记录表面上只是团队例行状态汇报但五大重点工程实际上勾勒了 Relay 此后十年的技术骨架2016 年 H1 计划当前仓库落点更简单/更快的核心Rust 编译器compiler/crates relay-runtime 核心数据层新连接 APIConnectionHandler.js usePaginationFragment.js低层 mutation APIcommitMutation.js RelayDeclarativeMutationConfig.js规范化响应格式RelayResponseNormalizer.js持久化查询project_config.rs operation_persister阅读这类会议记录价值在于还原为什么这么做的决策原点无论连接分页、声明式 mutation 还是持久化查询其出发点都指向同一个目标——在低端设备与弱网环境下保持优秀的开发者体验与运行时性能。对于想深入理解 Relay 架构设计的读者建议按上表从运行时核心源码入手再回到meta/meeting-notes/阅读相邻日期的会议记录即可拼出完整的演进脉络。【免费下载链接】relayRelay is a JavaScript framework for building>项目地址: https://gitcode.com/gh_mirrors/relay29/relay创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考