首页/新闻资讯/正文详情

Relay 部分缓存数据渲染(Partially Cached Data)实战指南:用 Fragment 边界与 Suspense 跳过加载态

发布时间:2026/9/23 21:38:22 来源:云帆数科 栏目:资讯中心
Relay 部分缓存数据渲染(Partially Cached Data)实战指南:用 Fragment 边界与 Suspense 跳过加载态
前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载本指南围绕 Relay 的部分渲染partial rendering能力展开当查询仅有部分数据被本地缓存时如何立即渲染已缓存的内容而不是等待整个网络请求完成。你将在本文中学到 Fragment 如何充当部分渲染的边界、fetchPolicy与renderPolicy的配合方式以及如何用Suspense精确控制哪些 UI 区域需要挂起等待最终在真实页面中跳过不必要的加载状态。什么是部分渲染在 Relay 中渲染缓存数据时查询并不总是需要全有或全无。所谓部分渲染partial rendering指的是一个查询的某些字段可能已经在本地缓存中而另一些字段尚未获取——在这种情况下我们希望立即渲染已缓存的部分而不是等待整个查询的完整响应返回后再一次性渲染。这在尽快呈现页面的场景下尤其有价值。以个人资料页profile page为例用户在 App 使用过程中其name字段很可能早已被其他查询缓存到本地 Relay Store 中。那么当用户再次访问资料页时即使该页面其余数据尚未就绪只要name已缓存我们也希望立刻渲染出这部分内容跳过整页的加载态。Fragment 是部分渲染的天然边界部分渲染之所以可行依赖的是Fragment 组件具备挂起suspend能力详见 Loading States with Suspense。规则如下一个 Fragment 组件在渲染时如果它本地声明locally declared的数据存在缺失、且该数据正在被网络请求获取那么它就会 suspend它会一直挂起到它所需要的数据被获取完毕也就是它所属的父查询parent query完成获取为止。关键在于一个判定细节Relay 只把本地声明且缺失的数据视为缺失。也就是说Fragment spread 内部选择的数据不会影响外层查询或外层 Fragment 的缺失判定。这一条规则正是部分渲染能成立的根基——正是它保证外层组件可以在子 Fragment 数据缺失时先行渲染。一个完整的示例name 已缓存、username 缺失假设我们有这样一个 Fragment 组件它只关心用户的username/** * UsernameComponent.react.js * * Fragment Component */ import type {UsernameComponent_user$key} from UsernameComponent_user.graphql; const React require(React); const {graphql, useFragment} require(react-relay); type Props { user: UsernameComponent_user$key, }; function UsernameComponent(props: Props) { const user useFragment( graphql fragment UsernameComponent_user on User { username } , props.user, ); return (...); } module.exports UsernameComponent;再假设有一个查询组件HomeTab它查询了User的name字段并在内部通过 Fragment spread 包含上述组件/** * AppTabs.react.js * * Query Loader Component */ // .... const onSelectHomeTab () { loadHomeTabQuery({id: 4}, {fetchPolicy: store-or-network}); } // ... /** * HomeTab.react.js * * Query Component */ const React require(React); const {graphql, usePreloadedQuery} require(react-relay); const UsernameComponent require(./UsernameComponent.react); function HomeTab(props: Props) { const data usePreloadedQuery( graphql query HomeTabQuery($id: ID!) { user(id: $id) { name ...UsernameComponent_user } } , props.queryRef, ); return ( h1{data.user?.name}/h1 UsernameComponent user{data.user} / / ); }现在假设渲染HomeTab时我们此前只获取过{id: 4}这个User的name它已经存在于当前 Relay environment 对应的本地 Store 中而username从未被缓存。使用允许复用缓存的 fetchPolicy 渲染会发生什么如果用fetchPolicy: store-or-network或store-and-network来渲染该查询过程如下查询先检查自身本地数据是否缺失。在本例中HomeTabQuery只在本地直接选择了name字段而name在 Store 中是存在的所以查询本身没有缺失数据。注意Fragment spread即...UsernameComponent_user内部选择的username不参与外层查询的缺失判定。查询没有缺失数据于是立即渲染随后尝试渲染子组件UsernameComponent。UsernameComponent渲染UsernameComponent_userFragment 时Relay 发现username缺失。此时该 Fragment 组件会 suspend直到网络请求完成。这里要特别强调无论选择哪种fetchPolicy只要整个查询包括 Fragment 内部有任何数据缺失就一定会发起网络请求——fetchPolicy只决定是否复用缓存、何时请求并不决定缺数据时是否请求。问题悬浮会向上冒泡当UsernameComponent因username缺失而 suspend 时理想情况是name已缓存应该立刻渲染出来。但如果我们没有用Suspense边界去捕获这个挂起那么suspension 会一路冒泡导致整个App组件树全部进入挂起状态已缓存的数据也无法显示。用 Suspense 包裹 Fragment实现真正意义上的部分渲染要达成name可用即渲染即使username缺失的目标只需用Suspense把UsernameComponent包裹起来允许App的其他部分继续渲染/** * HomeTab.react.js * * Query Component */ const React require(React); const {Suspense} require(React); const {graphql, usePreloadedQuery} require(react-relay); const UsernameComponent require(./UsernameComponent.react); function HomeTab() { const data usePreloadedQuery( graphql query AppQuery($id: ID!) { user(id: $id) { name ...UsernameComponent_user } } , props.queryRef, ); return ( h1{data.user?.name}/h1 {/* Wrap the UserComponent in Suspense to allow other parts of the App to be rendered even if the username is missing. */} Suspense fallback{LoadingSpinner labelFetching username /} UsernameComponent user{data.user} / /Suspense / ); }加上这个Suspense边界后h1{data.user?.name}/h1立即渲染出已缓存的nameUsernameComponent在自己的Suspense内挂起展示fallback例如Fetching username加载指示网络请求完成后UsernameComponent恢复渲染页面无缝补全。嵌套 Fragment 同样适用上述机制对嵌套 FragmentFragment 内再包含 Fragment完全成立如果渲染某个 Fragment 所需的数据已在本地缓存无论其子 Fragment 或后代 Fragment 的数据是否缺失该 Fragment 组件都能正常渲染如果子 Fragment 数据缺失只需在子 Fragment 外层包一层Suspense就能让其他 Fragment 和页面其余部分继续渲染。这意味着开发者可以把部分渲染的粒度做到非常细沿着组件树逐层设置Suspense边界让每个已缓存的区块独立呈现。正如开篇的动机示例所言这让我们能够完全跳过加载状态渲染出与最终状态更接近的中间 UI从而显著改善感知性能。源码视角fetchPolicy 与 renderPolicy 如何驱动部分渲染部分渲染并非魔法其底层决策逻辑可以在源码中找到明确对应。类型定义在 RelayRuntimeTypes.js 中定义了与本文相关的核心类型export type FetchQueryFetchPolicy store-or-network | network-only; export type FetchPolicy FetchQueryFetchPolicy | store-and-network | store-only; export type RenderPolicy full | partial;FetchPolicy决定数据从哪里来、何时发请求RenderPolicy决定查询结果在数据不完整时是否允许渲染——full表示必须数据完整才渲染partial表示允许渲染部分数据。决策逻辑在 QueryResource.js 的_fetchAndSaveQuery中Relay 对每个 fetchPolicy 计算两个关键布尔值const queryAvailability environment.check(operation); const queryStatus queryAvailability.status; const hasFullQuery queryStatus available; const canPartialRender hasFullQuery || (renderPolicy partial queryStatus ! stale); switch (fetchPolicy) { case store-only: { shouldFetch false; shouldAllowRender true; break; } case store-or-network: { shouldFetch !hasFullQuery; shouldAllowRender canPartialRender; break; } case store-and-network: { shouldFetch true; shouldAllowRender canPartialRender; break; } case network-only: default: { shouldFetch true; shouldAllowRender false; break; } }从这段实现可以推断store-or-network仅当查询有数据缺失时才发起网络请求shouldFetch !hasFullQuery同时若renderPolicy为partial且数据非 stale则允许先渲染store-and-network无论缓存是否完整都会发起请求shouldFetch true但同样允许在部分数据可用时先行渲染network-only忽略本地缓存、总是请求并且shouldAllowRender false——数据到达前在查询根处挂起因此不存在部分渲染store-only绝不发起请求总是渲染 Store 中已有的数据。注释也印证了挂起行为shouldAllowRender为false时Relay 会为查询缓存一个 Promise使查询在根节点处挂起为true时则缓存查询资源并允许渲染继续见 QueryResource.js。如何设置 renderPolicyRenderPolicy通常通过UNSTABLE_renderPolicy选项传入查询 hooks例如useLazyLoadQuery的 options见 useLazyLoadQuery.js也可通过 environment 的默认策略UNSTABLE_getDefaultRenderPolicy配置见 QueryResource.js。由于它以UNSTABLE_前缀标记属于实验性 API使用时请留意版本更新与迁移说明。实际应用建议先判断查询根是否可渲染只有查询本地直接声明的数据非 Fragment spread 内部全部可用时查询根才会渲染。因此骨架数据如name、id应尽量放在查询本身而不是埋进子 Fragment。按需设置 Suspense 边界在每一个可独立呈现的已缓存区块外层包Suspensefallback 使用局部占位如骨架屏、小型 spinner避免整页 spinner。组合 fetchPolicy 使用store-or-network是尽量复用缓存的默认选择若希望数据一进缓存就立刻刷新后台同步可改用store-and-network对必须强制新鲜的数据使用network-only会牺牲部分渲染。完整的行为定义可参考 fetch-policies 与 use-lazy-load-query 文档。了解相关的缓存机制部分渲染依赖 Store 中的数据可用性判定与之配套的概念还包括数据的存在性presence-of-data、数据陈旧性staleness-of-data以及缺失数据的填充filling-in-missing-data它们共同决定了哪些数据可以被立即渲染。小结Relay 的部分缓存数据渲染本质上是Fragment 边界 Suspense 边界的组合Fragment 的缺失判定只看本地声明数据这让外层查询能在子 Fragment 数据缺失时先行渲染在子 Fragment 外层包Suspense把挂起范围限制在局部让已缓存部分立即呈现底层由fetchPolicy控制是否发请求、renderPolicy控制是否允许部分渲染二者在 QueryResource.js 中协同决策。掌握这套机制后你可以为高频访问页面如资料页、列表页构建数据到了多少就渲染多少的渐进式 UI最大限度减少加载态对用户体验的打断。赞分享前端开发工具【免费下载链接】relayRelay is a JavaScript framework for building>项目地址https://gitcode.com/gh_mirrors/relay29/relay点击查看免费下载相关推荐Relay 部分缓存数据渲染Partially Cached Data完全指南用 Fragment 边界与 Suspense 跳过加载态Relay 部分缓存数据渲染Partially Cached Data完全指南用 Fragment 边界与 Suspense 跳过加载态 本篇指南以 Re前端开发工具Relay 部分缓存数据渲染Partially Cached Data实战指南Fragment 边界与 Suspense 的正确搭配Relay 部分缓存数据渲染Partially Cached Data实战指南Fragment 边界与 Suspense 的正确搭配 本篇指南面向使用 R前端开发工具Relay 部分缓存数据渲染指南用 Suspense 与 Fragment 边界跳过加载态Relay 部分缓存数据渲染指南用 Suspense 与 Fragment 边界跳过加载态 本篇指南聚焦 Relay 框架中“部分缓存渲染”Partial前端开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

AI换脸技术为何在影视级场景频频翻车?深度解析技术难点与工程实践
AI换脸技术为何在影视级场景频频翻车?深度解析技术难点与工程实践

1. 从《三千鸦杀》换脸翻车说起:AI换脸到底卡在哪《三千鸦杀》这部剧当年播出的时候,我正好在跟一个后期团队聊项目,群里有人甩了一张截图,就是那个被群嘲的换脸镜头。说实话,第一眼看上去确实出戏——脸是贴上了&… · 2026/9/23 21:38:22

C# .NET电商源码部署实战:从数据库还原到IIS发布全流程避坑指南
C# .NET电商源码部署实战:从数据库还原到IIS发布全流程避坑指南

简介:基于C#与.NET Framework开发的电子商务系统源码,面向需要构建B2B或B2C在线交易平台的开发者,也适合作为学习.NET电商架构的案例。压缩包大小5.58MB,已在CSDN获得1013次浏览/下载(文件数量与类型未在页面列出&… · 2026/9/23 21:38:22

Matlab双通道火灾检测:烟雾与火焰融合算法实战
Matlab双通道火灾检测:烟雾与火焰融合算法实战

简介:这份资源是一套基于Matlab实现的火灾检测系统源码包,面向计算机视觉与人工智能方向的初学者、课程设计者及算法开发者,用于解决视频或图像中烟雾与火焰的自动识别问题。系统分为烟雾检测与火焰检测两个模块,可应用于监控场景… · 2026/9/23 21:38:10

ALOHA协议吞吐率仿真与优化:从18.4%到时隙ALOHA的工程实践
ALOHA协议吞吐率仿真与优化:从18.4%到时隙ALOHA的工程实践

简介:这份资源围绕ALOHA与时隙ALOHA多址接入协议的性能仿真展开,面向无线通信、卫星通信及局域网方向的学习者与研究人员,帮助理解时隙划分、随机发送、碰撞检测与捕获效应等核心机制。压缩包共2个文件,均为m脚本文件,… · 2026/9/23 23:02:06

C# UHF RFID上位机开发:从DEMO到实战的串口通信与EPC解析
C# UHF RFID上位机开发:从DEMO到实战的串口通信与EPC解析

简介:这份资源是面向C#开发者与RFID入门者的UHF RFID阅读器演示工程,围绕UHFReader09型号设备,展示如何在.NET环境下完成标签读取、写入、解码及阅读器参数控制等核心操作。压缩包共52个文件、约660KB,以cs源代码为主体&#xff0… · 2026/9/23 23:02:06

LSTM时间序列预测实战:Python源码解析与调参避坑指南
LSTM时间序列预测实战:Python源码解析与调参避坑指南

简介:基于LSTM的时间序列分析预测Python源码,面向数据科学、人工智能方向的学习者与开发者。项目以空气污染数据为例,完整覆盖数据加载与归一化、LSTM模型构建(基于Keras/TensorFlow)、模型训练、评估与未来值预测等环… · 2026/9/23 23:01:53

长尾商品销量预测:基于DNN的时序预测与特征工程实战
长尾商品销量预测:基于DNN的时序预测与特征工程实战

简介:面向供应链备货中的长尾商品销量预测难题,这份基于TensorFlow 1.13编写的DNN项目源码,提供了7天、30天和60天三档预测的实现思路,适合有一定Python基础、希望借助低阶API掌握模型训练与部署的开发者。压缩包共6个文件&#x… · 2026/9/23 23:01:53

EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线
EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线

EverOS 记忆工作原理:Markdown 为源、SQLite 与 LanceDB 为派生索引的分层存储与同步管线 【免费下载链接】EverOS One portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflow… · 2026/9/23 23:01:41

鸵鸟目标检测数据集:419张VOC+YOLO双格式标注
鸵鸟目标检测数据集:419张VOC+YOLO双格式标注

简介:本资源是一份面向计算机视觉初学者与目标检测实践者的鸵鸟图像数据集,适用于YOLO、Faster R-CNN等主流检测模型的训练与验证。数据集共419张高质量JPG图像(1–500KB),全部标注为单一类别“ostrich”,并… · 2026/9/23 23:01:35

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码