新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/11/5 6:35:50来源:尧图网络
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),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/4 15:56:54

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/4 22:55:41

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/4 17:01:23

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/4 12:33:12

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/5 4:24:57

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/5 4:24:57

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉