next-partial-prefetching-optimizer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Partial Prefetching optimizer

Partial Prefetching 优化器

Optimize each requested source link and destination as its own contract. Turn the requested prefetched UI, navigation-only UI, and trigger into a production
instant()
test. Record the current behavior, make the smallest optimization, verify the differential, and keep the passing test as regression coverage.
Before making framework changes, read the bundled Optimizing prefetching guide at
node_modules/next/dist/docs/01-app/02-guides/optimizing-prefetching.md
. If the bundled guide is unavailable, use the online guide. It is the source of truth for prefetch stages,
prefetch={true}
, session-specific UI, and cost trade-offs.
When the work changes what belongs in the App Shell, follow the Instant navigation and Caching docs for cache placement, Suspense boundaries, loading UI, and authorization.
The guides own framework behavior and implementation patterns. This skill owns the navigation contract, production rig, trustworthy RED-to-GREEN loop, parity check, differential, and report.
This is not an adoption skill. If Cache Components or Partial Prefetching are not adopted, use their adoption skills and return to this workflow. If the App Shell itself cannot commit under
instant()
, use
next-cache-components-optimizer
first, then resume the selected navigation.
Run the workflow unattended. Resolve the contract from the request and the existing application. Stop for user input only when a product decision is genuinely blocked and cannot be inferred safely without changing cost, freshness, authorization, or user-visible behavior.
将每个请求的源链接和目标地址作为独立的约定进行优化。把请求的预取UI、仅导航时加载的UI和触发条件转化为生产环境的
instant()
测试。记录当前行为,进行最小范围的优化,验证差异,并将通过的测试保留为回归覆盖。
在修改框架行为之前,请阅读随附的《优化预取》指南,路径为
node_modules/next/dist/docs/01-app/02-guides/optimizing-prefetching.md
。如果随附指南不可用,请使用在线指南。该指南是预取阶段、
prefetch={true}
、会话专属UI以及成本权衡的权威依据。
当工作内容涉及修改App Shell的组成时,请参考Instant navigationCaching文档,了解缓存放置、Suspense边界、加载UI和授权相关的规范。
这些指南负责定义框架行为和实现模式。本Skill负责导航约定、生产环境rig、可靠的RED-to-GREEN循环、一致性检查、差异验证和报告。
这不是一个接入类Skill。如果尚未采用Cache Components或Partial Prefetching,请使用对应的接入Skill,再返回本工作流。如果App Shell本身无法在
instant()
下通过验证,请先使用
next-cache-components-optimizer
,再继续处理选中的导航。
以无人值守方式运行工作流。根据请求和现有应用确定导航约定。仅当产品决策确实受阻,且在不改变成本、新鲜度、授权或用户可见行为的前提下无法安全推断时,才暂停等待用户输入。

Reporting to the user

向用户报告

This loop runs unattended, so do not stop between implementation steps. Finish the navigations the user named, then check in. The rig, lock, RED/GREEN loop, and stage names are internal scaffolding; report the product behavior instead.
  • Speak their language. Describe the source link and result in terms of what the user sees before and after the click, not the validation mechanics.
  • Show, don't tell. Drive the exact link in a production browser so the user sees which content is already available and which content streams after the click. If a live demonstration is unavailable, attach before/after captures.
  • Give them a concise click-through list, not a technical results table. Use one line per navigation with the source URL, link to click, UI ready before the click, UI that waits for navigation, and whether prefetching starts in the viewport or after intent.
  • Only surface a question for a genuine fork. Ask when the choice changes cost, freshness, authorization, or visible behavior. If the user already requested a PR or named every navigation, finish that scope without asking again.
该循环以无人值守方式运行,因此不要在实现步骤之间暂停。完成用户指定的所有导航优化后,再进行反馈。rig、锁、RED/GREEN循环和阶段名称都属于内部实现细节;应向用户报告产品层面的行为变化。
  • 使用用户的语言。 从用户点击前后看到的内容角度描述源链接和优化结果,而不是讲解验证机制。
  • 展示而非告知。 在生产环境浏览器中直接操作对应的链接,让用户看到哪些内容在点击前已经可用,哪些内容会在点击后流式加载。如果无法进行实时演示,请附上点击前后的截图。
  • 提供简洁的点击体验列表,而非技术结果表格。 每个导航占一行,包含源URL、待点击链接、点击前已就绪的UI、等待导航触发后加载的UI,以及预取是在视口内启动还是在用户产生意图后启动。
  • 仅在存在真正的分歧时才提出问题。 当选择会影响成本、新鲜度、授权或可见行为时,再询问用户。如果用户已经要求提交PR或指定了所有需要优化的导航,请直接完成对应范围的工作,无需再次询问。

Define the contract

定义约定

Inspect the source route, the exact link or interaction, the destination's Suspense boundaries, its data reads, existing prefetch policy, and any existing
instant()
test. Record:
  • which destination UI should be ready before the click;
  • which reusable UI should wait for navigation;
  • whether per-link prefetching should start in the viewport or only after intent.
The trigger is part of the contract. Two links to the same URL may use different prefetch policies and need separate tests.
Use the guide's cost model when the trigger is not already specified. Do not silently increase the number of links that can invoke the server or cache data whose freshness contract is unknown.
检查源路由、具体的链接或交互方式、目标页面的Suspense边界、数据读取逻辑、现有预取策略,以及任何已有的
instant()
测试。记录以下内容:
  • 哪些目标页面UI应在点击前就绪;
  • 哪些可复用UI应等待导航触发后再加载;
  • 每个链接的预取是应在视口内启动,还是仅在用户产生意图后启动。
触发条件是约定的一部分。指向同一URL的两个链接可能使用不同的预取策略,因此需要单独的测试。
如果未指定触发条件,请参考指南中的成本模型。不要私自增加可调用服务器的链接数量,也不要私自缓存新鲜度约定不明确的数据。

Reuse the production rig

复用生产环境rig

Read an existing
instant-nav.rig.md
. Cache Components optimization, Partial Prefetching adoption, and this optimizer share the same build, auth, data, and Playwright contract. Add the exact source link, destination markers, and prefetch budget instead of creating another rig.
If the project has no rig, use
rig-template.md
to discover and record one. The measured run must be a production build or preview where
experimental.exposeTestingApiInProductionBuild
is enabled only for testing. Development can help diagnose a route, but automatic link prefetching is production-only.
读取已有的
instant-nav.rig.md
文件。Cache Components优化、Partial Prefetching接入和本优化器共享同一套构建、认证、数据和Playwright约定。只需添加具体的源链接、目标标记和预取预算,无需创建新的rig。
如果项目没有rig,请使用
rig-template.md
来梳理并记录一套。测试运行必须基于生产构建或预览版本,其中
experimental.exposeTestingApiInProductionBuild
仅在测试时启用。开发环境可以帮助诊断路由问题,但自动链接预取仅在生产环境中生效。

Prove the current behavior

验证当前行为

Search for an existing
instant()
test for the exact source link and destination. Extend it when it already covers the same behavior. Otherwise, add a focused click-driven test using the guide's prefetched and deferred content testing pattern.
Keep one production browser test per source-link, destination, and trigger contract. Do not loop over several destinations or collect their readiness results in one test. Focused tests can still run serially in one browser worker.
First, run an unlocked scaffold that proves the link reaches the exact pathname and query and that the selected UI eventually renders for the test user. Do not ship this scaffold.
Then run the same interaction inside
instant()
. The existing App Shell must stay visible, while the guide's positive and negative assertions capture the prefetched result. After the lock releases, every selected region must eventually render.
Read
reference/red-test-robustness.md
before treating this failure as RED. A timeout before the URL changes, a missing App Shell, a redirect, missing data, or a stale preview indicates a rig or route problem. It does not justify changing prefetching.
If the complete desired contract already passes under the lock, stop. Never add
prefetch={false}
merely to manufacture a RED.
Only test files and the configuration needed to expose the testing API may change before these runs finish. Run builds and tests in the foreground. If the harness moves one into the background, wait for it to exit and continue the loop in the same task. A written test or a build still in progress is not verification.
查找是否已有针对该源链接和目标地址的
instant()
测试。如果已有测试覆盖了相同的行为,请对其进行扩展。否则,请使用指南中的预取与延迟内容测试模式,添加一个聚焦于点击驱动的测试。
每个源链接、目标地址和触发条件的约定,对应一个生产环境浏览器测试。不要在一个测试中循环测试多个目标地址,也不要在一个测试中收集多个页面的就绪结果。聚焦型测试仍然可以在一个浏览器工作进程中串行运行。
首先运行一个未锁定的测试脚手架,验证该链接能跳转到准确的路径名和查询参数,并且选中的UI最终能为测试用户渲染。不要提交这个脚手架代码。
然后在
instant()
中运行相同的交互。现有App Shell必须保持可见,同时使用指南中的正向和反向断言来验证预取结果。锁释放后,所有选中的区域都必须最终渲染完成。
在将该失败判定为RED之前,请先阅读
reference/red-test-robustness.md
。URL变更前超时、App Shell缺失、重定向、数据缺失或预览过期,都说明是rig或路由存在问题,不能作为修改预取逻辑的依据。
如果完整的预期约定在锁定状态下已经通过测试,请停止操作。绝不要为了制造RED而添加
prefetch={false}
在这些运行完成之前,仅可修改测试文件和暴露测试API所需的配置。在前台运行构建和测试。如果测试框架将某个任务移到了后台,请等待其退出,并在同一任务中继续循环。编写完成的测试或仍在进行的构建都不能算作验证完成。

Make the smallest optimization

进行最小范围优化

Follow the Optimizing prefetching guide for stage and link policy. If the contract also requires changing cache placement, Suspense, or loading UI, follow the static-shell documentation used by
next-cache-components-optimizer
. Preserve the existing freshness and authorization behavior. Change only what the selected contract requires.
When reusable UI should wait for navigation, follow the
unstable_navigation()
reference, including its comparison with
connection()
. Then verify both properties independently. The
instant()
assertion proves that the UI is absent from the prefetch; it does not prove that the underlying work stayed reusable. Verify that reusable work remains cached below the stage boundary.
When the contract needs an explicit runtime stage, follow the API references for
unstable_prefetch()
and
unstable_navigation()
.
Work one accepted navigation to GREEN before moving to another. Do not create an app-wide Link or cache abstraction from a single case.
If the optimization adds or expands a cache boundary, follow Revalidating. When a writer can change that cached data, test the complete lifecycle: populate the cache, perform the mutation, then read the data again and verify the updated value. A passing
instant()
test proves prefetched readiness, not mutation freshness.
请遵循《优化预取》指南来设置阶段和链接策略。如果约定还需要修改缓存放置、Suspense或加载UI,请遵循
next-cache-components-optimizer
使用的静态壳文档。保留现有的新鲜度和授权行为。仅修改选中的约定所要求的内容。
当可复用UI需要等待导航触发后再加载时,请参考
unstable_navigation()
文档,包括其与
connection()
的对比说明。然后分别验证这两个属性。
instant()
断言只能证明UI不在预取内容中,但不能证明底层的工作仍然是可复用的。需要验证可复用的工作仍然缓存在阶段边界之下。
当约定需要明确的运行时阶段时,请参考
unstable_prefetch()
unstable_navigation()
的API文档。
先将一个已确认的导航优化到GREEN,再处理下一个。不要基于单个案例创建全应用范围的Link或缓存抽象。
如果优化添加或扩展了缓存边界,请遵循Revalidating文档的要求。当写入操作可以修改该缓存数据时,请测试完整的生命周期:填充缓存,执行数据变更,然后重新读取数据并验证更新后的值。通过
instant()
测试只能证明预取已就绪,不能证明数据变更后的新鲜度。

Verify and ship

验证与发布

Keep the passing locked test for the real source link as regression coverage. Preserve the loaded page's content, ordering, empty and error states, authorization, freshness, redirects, and direct-load behavior.
Finally, remove only the optimization and rerun the test:
  • the App Shell stays GREEN;
  • the selected prefetch contract returns RED.
Reapply the optimization and require GREEN again. This differential proves the test guards the exact link policy instead of unrelated cached state. Ship only the final positive test.
Report the verified result using the user-facing format above. Be precise that prefetching is best-effort; the App Shell remains the fallback when it has not completed.
Treat request counts, transferred bytes, and cache behavior as measurements, not as part of the
instant()
contract. Do not classify requests using private RSC URLs or internal headers such as
next-router-prefetch
. The public testing API verifies the rendered result, not the protocol stage that produced each request.
将真实源链接的通过状态的锁定测试保留为回归覆盖。保留已加载页面的内容、顺序、空状态和错误状态、授权、新鲜度、重定向以及直接加载行为。
最后,仅移除优化代码,重新运行测试:
  • App Shell保持GREEN;
  • 选中的预取约定返回RED。
重新应用优化代码,再次确认测试为GREEN。这种差异验证证明了该测试确实是在保护对应的链接策略,而不是无关的缓存状态。仅发布最终的正向测试。
使用上述面向用户的格式报告验证结果。请明确说明预取是尽力而为的;当预取未完成时,App Shell仍然是降级方案。
将请求数、传输字节数和缓存行为视为衡量指标,而不是
instant()
约定的一部分。不要使用私有RSC URL或内部请求头(如
next-router-prefetch
)来对请求进行分类。公共测试API验证的是渲染结果,而不是生成每个请求的协议阶段。

Completion checklist

完成检查清单

  • Cache Components and Partial Prefetching were already adopted.
  • The target UI, trigger, freshness, and authorization constraints were resolved from the request and existing application.
  • The test clicks the exact source link and verifies the exact destination.
  • Each source-link, destination, and trigger contract has its own test.
  • The unlocked baseline and locked RED used the same production artifact.
  • The App Shell stayed visible throughout the RED/GREEN loop.
  • The selected UI is present and navigation-only UI is absent under lock.
  • Reusable navigation-only work remains cached below its navigation stage.
  • After populating any new cache whose data can be updated, a mutation test confirms the next read returns the expected data.
  • Loaded content, freshness, authorization, and direct visits are unchanged.
  • Removing only the optimization returns the contract to RED.
  • The final positive
    instant()
    regression test ships.
  • 已采用Cache Components和Partial Prefetching。
  • 已根据请求和现有应用确定了目标UI、触发条件、新鲜度和授权约束。
  • 测试点击了准确的源链接,并验证了准确的目标地址。
  • 每个源链接、目标地址和触发条件的约定都有对应的测试。
  • 未锁定的基线测试和锁定的RED测试使用了相同的生产构建产物。
  • 在整个RED/GREEN循环过程中,App Shell始终保持可见。
  • 锁定状态下,选中的UI已加载,仅导航时加载的UI未出现。
  • 可复用的仅导航工作仍然缓存在其导航阶段之下。
  • 对于数据可更新的新缓存,在填充缓存后,已通过数据变更测试确认后续读取会返回预期数据。
  • 已加载内容、新鲜度、授权和直接访问行为均未改变。
  • 仅移除优化代码后,约定返回RED状态。
  • 最终的正向
    instant()
    回归测试已发布。

Handoff

交接

Finish every navigation named in the request. If Cache Components or Partial Prefetching are not adopted, use
next-cache-components-adoption
or
next-partial-prefetching-adoption
, then return to this workflow. If the App Shell cannot commit under
instant()
, use
next-cache-components-optimizer
and resume the selected navigation afterward. Do not leave a build or test for the user to monitor.
Report additional optimization candidates without changing them unless they are already in scope. Do not broaden a selected per-link policy into an app-wide Link or cache abstraction.
完成请求中指定的所有导航优化。如果尚未采用Cache Components或Partial Prefetching,请使用
next-cache-components-adoption
next-partial-prefetching-adoption
Skill,再返回本工作流。如果App Shell无法在
instant()
下通过验证,请先使用
next-cache-components-optimizer
,再继续处理选中的导航。不要留下需要用户监控的构建或测试任务。
报告额外的优化候选项,但不要修改它们,除非它们已在范围内。不要将选中的单链接策略扩展为全应用范围的Link或缓存抽象。

Files

文件

  • rig-template.md
    : production build, test context, navigation contract, and unattended loop discovery for projects without an existing
    instant-nav.rig.md
    .
  • reference/red-test-robustness.md
    : trustworthy RED and differential checks.
  • rig-template.md
    :适用于没有现有
    instant-nav.rig.md
    的项目,包含生产构建、测试上下文、导航约定和无人值守循环的梳理说明。
  • reference/red-test-robustness.md
    :可靠的RED和差异验证检查说明。

Further reading

延伸阅读