ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Relay 团队 2016-05-03 开发同步:从 RelayConnection 到低层 Mutation API 的演进切片

Relay 团队 2016-05-03 开发同步:从 RelayConnection 到低层 Mutation API 的演进切片 前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载2016 年 5 月 3 日Relay 团队在内部同步会上分享了各自的状态更新内容横跨数据获取、持久化查询、分页连接、垃圾回收原型与全新 mutation API。这篇技术指南以该次会议纪要为主线结合本仓库现行源码逐条还原当时正在攻坚的技术点并对照今天的实现验证其演进轨迹帮助读者理解 Relay 的核心机制连接分页、持久化查询、乐观更新、GC是如何一步步成型的。会议背景为什么要公开团队同步纪要本次纪要存放于仓库 meta/meeting-notes/README.md其中明确说明了这批文档的由来从 2016 年 2 月起Facebook 的 Relay 团队决定将内部会议纪要发布到项目仓库中原因是团队在 Relay 上的许多工作对外不可见即便可见外部用户也未必有足够上下文去理解它。公开纪要是为了让开发过程尽可能透明也让外部社区能跟踪 Relay 的发展脉络。本文解析的 2016-05-03-team-sync.md 正是这一透明化实践中的一环记录了一次典型的团队状态同步。一、低层 Mutation API为大规模改造铺路1.1 纪要中的进展本次同步中wincent 的状态更新包括在低层 mutation API 上完成了点赞likes与取消点赞unlikes功能评论 mutation 正在低层 mutation API 上推进持续进行清理工作与 Flow 类型修复持续移植更多 mutation 以验证该 API 的可行性。同一天yuzhi 也提到正在修复带 calls 的乐观 payloadoptimistic payloads with calls。这两条信息相互印证当时团队正在将 mutation 从旧的容器式 API 向更底层的、面向记录的 mutation API 迁移并同步解决乐观更新optimistic update在带参数调用场景下的数据正确性问题。1.2 演进到今天的形态今天这套低层 mutation API 的遗产体现在 packages/relay-runtime/mutations/ 目录中commitMutation、applyOptimisticMutation、commitLocalUpdate等 API 构成了 Relay 现代 mutation 的核心。当时的乐观 payload概念对应今天commitMutation的optimisticResponse/optimisticUpdater参数——客户端在服务端响应返回前先应用预期数据从而获得即时 UI 反馈。从会议纪要到现代实现可以看到一条清晰的演进线低层 API 的价值在于让 mutation 逻辑与 UI 容器解耦使点赞、评论这类高频交互可以被独立复用与测试这也正是今天 commitMutation.js 所承担的职责。二、mutation 调试辅助与 root call ID 的正确存储2.1 纪要中的进展yuzhi 的三项工作都指向 mutation 数据流的健壮性合入了mutation debug helper调试辅助工具用于观测 mutation 执行链路发现并修复了root call ID 存储方式的问题正在修复带 calls 的乐观 payload。其中root call ID是理解 Relay 数据归一化normalization的关键概念Relay 将服务端返回的每条记录按其 ID 存储到本地 store 中而 root call如node(id: $id)的调用参数与结果之间的映射关系必须被正确记录否则后续查询无法复用已缓存的数据。这一修复保证了以 ID 为根参数的查询在缓存中能够被稳定地关联和复用。2.2 在仓库中的对应物这类 root 记录存储与 ID 归一化逻辑今天可以在 packages/relay-runtime/store/RelayResponseNormalizer.js响应归一化与 packages/relay-runtime/store/RelayModernRecord.js记录存储中看到其完整实现。调试辅助的理念则演化为 packages/relay-runtime/util/RelayProfiler.js 之类的可插拔观测机制。三、RelayConnection分页连接的原型期3.1 纪要中的进展steveluscher 与 kassens 当时围绕RelayConnection展开了密集工作合入了cache processor 与 restorer traversals缓存处理器与恢复器遍历即从缓存重建连接状态的能力讨论了RelayConnection与 prototype 的关系规划正在完成RelayConnection 的磁盘缓存集成RelayConnection的持久化查询工作已在进行中[kassens]。RelayConnection是后来官方 Connection 规范见 website/spec/Connections.md的前身它定义了如何对列表数据进行分页前向/后向、如何维护页面信息pageInfo、如何在多次加载之间追加/合并 edges以及当服务端未返回全部列表时如何保持客户端一致性。3.2 今天的实现现代 Relay 中Connection 的客户端逻辑集中在 packages/relay-runtime/handlers/connection/ 目录下。当时纪要提到的缓存处理器 恢复器遍历对应今天 Connection handler 中从 store 重建 connection 状态、维护__id、__range等内部字段的复杂逻辑从缓存直接获取的能力也演化为今天usePaginationFragment、useRefetchableFragment等 hook 与 getConnectionState.js 中可见的头部/尾部加载状态管理。当时head loads向连接头部插入新数据典型场景是发布新内容后置顶等能力也正是在这段原型期逐步定型的。四、100% deferred fragments 缺陷延迟加载的早期困扰4.1 纪要中的进展steveluscher 修复了100% deferred fragments100% 延迟的 fragment问题同时 josephsavona 也在处理同一缺陷及相关问题。100% deferred fragment指的是整个查询的全部内容都被标记为延迟加载deferred的边界情况——当没有任何同步数据可供渲染时客户端必须正确进入加载状态而不是挂起或崩溃。这看似是极端场景却暴露出 Relay 数据获取调度器在同步/异步边界处理上的核心难点。4.2 在今天代码中的痕迹延迟加载deferred与同步/异步执行的编排在现代 Relay 中由 packages/relay-runtime/store/OperationExecutor.js 等执行器负责。虽然 2016 年的具体 bug 早已修复但其背后正确处理部分加载结果的原则持续影响着今天usePreloadedQuery、defer相关的能力设计与测试覆盖。五、GC-by-default 原型Relay 垃圾回收的起点5.1 纪要中的进展josephsavona 在实验性原型中完成了GC-by-default默认启用垃圾回收的 proof-of-concept并用WindowedListView窗口化列表视图搭建了一个照片流 demo计划周末前完成示例应用。这是 Relay 内存管理史上的关键节点Relay 将 GraphQL 数据归一化存储后store 会持续累积不再被任何活跃组件引用的记录若不回收将导致内存无限增长。当时GC-by-default的设想正是要为 store 引入基于引用计数的回收机制。5.2 今天的实现现代 Relay 的垃圾回收实现在 packages/relay-runtime/store/RelayModernStore.js 中store 跟踪每条记录的引用情况当某个查询/订阅/持有者被释放release后不再被引用的记录会被调度回收。这正是当年 proof-of-concept 的工程化落地。同期纪要如 2016-05-31-team-sync.md提到的隐式引用计数版本与手动引用计数版本两种原型也最终收敛为今天默认启用的引用计数 GC 策略。六、持久化查询Persisted Queries的早期验证6.1 纪要中的进展kassens 当时的工作包括修复测试确保persisted queries 始终是最新的修复两个仓库之间 diff 的同步问题着手RelayConnection 的持久化。同时 wincent 合入了关闭 tracked queries跟踪查询的 diff——这表明团队当时正在从客户端携带完整查询文本 服务端跟踪的模式转向客户端只携带查询 ID的持久化模式。6.2 今天的使用方式持久化查询在今天有完整的官方指南website/docs/guides/persisted-queries.mdx其核心收益在 2016 年就已被识别客户端传输内容从完整查询文本变为 md5 哈希显著减少上行字节数服务端可以对操作进行白名单化allowlist限制客户端可执行的查询提升安全性。当时的持久化RelayConnection也印证了持久化与分页的组合使用分页查询同样需要被持久化才能享受同样的带宽与安全收益。6.3 编译器侧的现代实现在今天的 Rust 编译器中持久化由两个实现承担定义于 operation_persister.rsLocalPersisterlocal_persister.rs将 GraphQL 文档存到磁盘文件。源码显示它支持MD5、SHA1、SHA256三种哈希算法由relay_config::LocalPersistAlgorithm决定并将operation_id 完整查询文本的映射以 JSON 形式写入配置文件指定的路径若文件不存在首次运行则从空映射开始finalize时统一写出。RemotePersisterremote_persister.rs通过 HTTP POST 将查询文本发送到远端持久化服务换取查询 ID——这正是指南中persistConfig的url/params配置所驱动的行为。配置侧compiler.rs 等模块中可看到persist_config、repersist_operations即使文本哈希匹配也强制重新持久化、export_persisted_query_ids_to_file导出持久化查询 ID 列表等选项说明该机制在编译器层面已是完整的、可配置的一等公民。2016 年那份修复测试以确保持久化查询最新的工作也对应今天编译器在构建时自动校验/更新持久化产物的行为。七、平台兼容与工程基建isNaN polyfill 与 Flow 修复7.1 纪要中的进展steveluscher 修复了React Native 上的isNaNpolyfill问题——RN 运行环境与浏览器宿主存在差异需要补齐标准库能力。这与 wincent 的清理工作与 Flow 修复一起代表了当时团队对跨平台兼容性与类型安全的持续投入。7.2 意义这类工作虽不起眼却是 Relay 能同时运行在 Web 与 React Native 上的基石。今天仓库中 packages/relay-runtime/util/ 下大量小而专的工具函数如RelayError、deepFreeze、generateID等正是这种宿主环境无关工程哲学的延续——运行时只依赖最小限度的标准能力差异部分由各平台适配。八、外部连接与社区建设tech talks 与 zero-to-graphql纪要还记录了团队的对外活动技术演讲已上线官网见当时的 videos 页面对 zero-to-graphql 收到了大量反馈包括一个 Scala 版本 PR。这些信息表明2016 年的 Relay 团队在推进核心架构的同时也在积极经营开发者社区、产出教学资源。这与会议纪要公开化的初衷一致——让 Relay 的为什么与怎么做同样透明。结语从一次同步会看到 Relay 的架构主线回看 2016-05-03-team-sync.md 这份纪要一天之内并行推进的工作几乎覆盖了 Relay 的全部核心机制分页连接RelayConnection、持久化查询、乐观更新、延迟加载、垃圾回收与低层 mutation API。十年后的今天这些概念分别沉淀在 packages/relay-runtime/handlers/connection/、persisted-queries 指南、mutations 目录、RelayModernStore.js 与 OperationExecutor.js 中。对于阅读 Relay 源码或使用 Relay 构建应用的开发者这份纪要的价值在于它揭示了这些机制的问题起源——Relay 的每一项设计都不是凭空而来而是对真实产品痛点带宽、内存、即时反馈、跨平台的直接回应。理解 2016 年的这些攻坚点能帮助你更快地在今天的代码库中定位对应实现并理解其设计取舍。赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay 团队 2016-07-05 会议同步纪要解读从原型验证到生产落地的关键转折Relay 团队 2016 07 05 会议同步纪要解读从原型验证到生产落地的关键转折 本文基于 Relay 官方仓库 meta/meeting notes/前端开发工具从 2016-09-06 团队同步看 Relay 1→2 互操作与现代化容器能力演进从 2016 09 06 团队同步看 Relay 1→2 互操作与现代化容器能力演进 本篇文章以 relay 仓库中 2016 09 06 的团队同步会议纪要前端开发工具从 2016 年团队同步看 Relay 2 核心能力兼容容器、分页、Refetching 与 Watchman 驱动的代码生成从 2016 年团队同步看 Relay 2 核心能力兼容容器、分页、Refetching 与 Watchman 驱动的代码生成 2016 年 9 月 20 日前端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表