预取
页面加载时间在网站的可用性和整体体验中扮演着重要角色。Astro 的选择性加入预取功能,可以在访问者与你的多页应用(MPA)交互时,为他们带来近乎即时的页面导航体验。
启用预取
标题为“启用预取”的部分你可以通过 prefetch
配置来启用预取功能
import { defineConfig } from 'astro/config';
export default defineConfig({ prefetch: true});
一个预取脚本将被添加到你网站的所有页面。然后,你可以将 data-astro-prefetch
属性添加到网站上的任何 <a />
链接中,以选择性地启用预取。当您将鼠标悬停在链接上时,该脚本将在后台获取页面。
<a href="/about" data-astro-prefetch>
请注意,预取仅适用于你网站内部的链接,不适用于外部链接。
预取配置
标题为“预取配置”的部分prefetch
配置也接受一个选项对象以进一步自定义预取。
预取策略
标题为“预取策略”的部分Astro 支持 4 种预取策略,以适应不同的使用场景
hover
(默认):当您悬停或聚焦在链接上时进行预取。tap
:在您点击链接之前进行预取。viewport
:当链接进入视口时进行预取。load
:页面加载后,预取页面上的所有链接。
你可以通过将策略传递给 data-astro-prefetch
属性来为单个链接指定策略
<a href="/about" data-astro-prefetch="tap">About</a>
每种策略都经过微调,仅在需要时进行预取,以节省用户的带宽。例如
默认预取策略
标题为“默认预取策略”的部分添加 data-astro-prefetch
属性时的默认预取策略是 hover
。要更改它,你可以在你的 astro.config.mjs
文件中配置prefetch.defaultStrategy
import { defineConfig } from 'astro/config';
export default defineConfig({ prefetch: { defaultStrategy: 'viewport' }});
默认预取所有链接
标题为“默认预取所有链接”的部分如果你想预取所有链接,包括那些没有 data-astro-prefetch
属性的链接,你可以将prefetch.prefetchAll
设置为 true
import { defineConfig } from 'astro/config';
export default defineConfig({ prefetch: { prefetchAll: true }});
然后,你可以通过设置 data-astro-prefetch="false"
来为单个链接选择退出预取
<a href="/about" data-astro-prefetch="false">About</a>
所有链接的默认预取策略可以通过 prefetch.defaultStrategy
进行更改,如默认预取策略部分所示。
以编程方式预取
标题为“以编程方式预取”的部分由于某些导航可能不总是以 <a />
链接的形式出现,你也可以使用 astro:prefetch
模块中的 prefetch()
API 以编程方式进行预取
<button id="btn">Click me</button>
<script> import { prefetch } from 'astro:prefetch';
const btn = document.getElementById('btn'); btn.addEventListener('click', () => { prefetch('/about'); });</script>
prefetch()
API 包含了相同的省流模式和慢速连接检测,因此它只在需要时进行预取。
要忽略慢速连接检测,你可以使用 ignoreSlowConnection
选项
// Prefetch even on data saver mode or slow connectionprefetch('/about', { ignoreSlowConnection: true });
eagerness
标题为“eagerness”的部分类型: 'immediate' | 'eager' | 'moderate' | 'conservative'
默认值: 'immediate'
astro@5.6.0
在启用实验性clientPrerender
标志后,你可以在 prefetch()
上使用 eagerness
选项,向浏览器建议它应该以多大的“渴望度”来预取/预渲染链接目标。
这遵循 Speculation Rules API 中描述的相同 API,并默认为 immediate
(最“渴望”的选项)。按渴望度降序排列,其他选项是 eager
、moderate
和 conservative
。
eagerness
选项允许你在减少等待时间的好处与网站访问者的带宽、内存和 CPU 成本之间取得平衡。一些浏览器,如 Chrome,已经设置了限制以防止过度推测(预渲染/预取太多链接)。
------<script>// Control prefetching eagerness with `experimental.clientPrerender`import { prefetch } from 'astro:prefetch';
// This page is resource-intensiveprefetch('/data-heavy-dashboard', { eagerness: 'conservative' });
// This page is critical to the visitor's journeyprefetch('/getting-started'); // defaults to `{ eagerness: 'immediate' }`
// This page may not be visitedprefetch('/terms-of-service', { eagerness: 'moderate' });</script>
要在大量链接上以编程方式使用 prefetch()
,你可以设置 eagerness: 'moderate'
,以利用先进先出(FIFO)策略和浏览器启发式算法,让浏览器决定何时以及以何种顺序预渲染/预取它们
<a class="link-moderate" href="/nice-link-1">A Nice Link 1</a><a class="link-moderate" href="/nice-link-2">A Nice Link 2</a><a class="link-moderate" href="/nice-link-3">A Nice Link 3</a><a class="link-moderate" href="/nice-link-4">A Nice Link 4</a>...<a class="link-moderate" href="/nice-link-20">A Nice Link 20</a>
<script> import { prefetch } from 'astro:prefetch';
const linkModerate = document.getElementsByClassName('link-moderate'); linkModerate.forEach((link) => prefetch(link.getAttribute('href'), {eagerness: 'moderate'}));
</script>
确保只在客户端脚本中导入 prefetch()
,因为它依赖于浏览器 API。
与视图转换一起使用
标题为“与视图转换一起使用”的部分当你在页面上使用Astro 的 <ClientRouter />
时,预取也将默认启用。它会设置一个默认配置 { prefetchAll: true }
,从而为页面上的所有链接启用预取。
你可以在 astro.config.mjs
中自定义预取配置来覆盖默认值。例如
import { defineConfig } from 'astro/config';
export default defineConfig({ // Disable prefetch completely prefetch: false});
import { defineConfig } from 'astro/config';
export default defineConfig({ // Keep prefetch, but only prefetch for links with `data-astro-prefetch` prefetch: { prefetchAll: false }});
浏览器支持
标题为“浏览器支持”的部分Astro 的预取功能在浏览器支持的情况下使用 <link rel="prefetch">
,否则回退到 fetch()
API。
最常见的浏览器都支持 Astro 的预取功能,但存在细微差别
Chrome
标题为“Chrome”的部分Chrome 支持 <link rel="prefetch">
。预取功能按预期工作。
它还完全支持来自 Speculation Rules API 的 <script type="speculationrules">
,可用于进一步描述预取策略和规则,从而增强 Chrome 用户的体验。你需要启用clientPrerender
实验性功能才能在 prefetch()
中使用此功能
Firefox
标题为“Firefox”的部分Firefox 支持 <link rel="prefetch">
,但可能会显示错误或完全失败
- 如果没有显式的缓存头(例如
Cache-Control
或Expires
),预取将报错NS_BINDING_ABORTED
。 - 即使发生错误,如果响应具有正确的
ETag
头,它也将在导航时被重用。 - 否则,如果它在没有其他缓存头的情况下出错,预取将无法工作。
Safari
标题为“Safari”的部分Safari 不支持 <link rel="prefetch">
,将回退到 fetch()
API,这需要设置缓存头(例如 Cache-Control
、Expires
和 ETag
)。否则,预取将无法工作。
边缘情况: ETag
标头在隐私窗口中不起作用。
为了最好地支持所有浏览器,请确保你的页面具有正确的缓存头。
对于静态或预渲染的页面,ETag
头通常由部署平台自动设置,并有望开箱即用。
对于动态和服务器端渲染的页面,请根据页面内容自行设置适当的缓存头。请访问 MDN 关于 HTTP 缓存的文档以获取更多信息。
从 @astrojs/prefetch 迁移
标题为“从 @astrojs/prefetch 迁移”的部分@astrojs/prefetch
集成已在 v3.5.0 中被弃用,并将最终被完全移除。请按照以下说明迁移到 Astro 的内置预取功能,该功能取代了此集成。
-
移除
@astrojs/prefetch
集成,并在astro.config.mjs
中启用prefetch
配置astro.config.mjs import { defineConfig } from 'astro/config';import prefetch from '@astrojs/prefetch';export default defineConfig({integrations: [prefetch()],prefetch: true}); -
从
@astrojs/prefetch
的配置选项转换-
已弃用的集成使用
selector
配置选项来指定哪些链接在进入视口时应被预取。请改为向这些单独的链接添加
data-astro-prefetch="viewport"
。<a href="/about" data-astro-prefetch="viewport"> -
已弃用的集成使用
intentSelector
配置选项来指定哪些链接在被悬停或聚焦时应被预取。请改为向这些单独的链接添加
data-astro-prefetch
或data-astro-prefetch="hover"
<!-- You can omit the value if `defaultStrategy` is set to `hover` (default) --><a href="/about" data-astro-prefetch><!-- Otherwise, you can explicitly define the prefetch strategy --><a href="/about" data-astro-prefetch="hover"> -
来自
@astrojs/prefetch
的throttles
选项不再需要,因为新的预取功能将自动进行最佳的调度和预取。
-