-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configure Astro prefetch behaviour #201
Comments
Personally I always had my doubts with prefetching of pages. I think it comes from large bundle splitted client(or hybrid) side rendered JS heavy apps where you actually run into performance issues on lower end CPU devices that struggle with parsing and executing JS. I even think that caching and prefetching in some setups actually include the parsing of JS. So I think it stems from (partially) solving an actual performance problem. In our setup and context I have these considerations:
My initial humble opinion is that we need to add a lot of complexity in order to have little benefits, while overfetching. But to answer your questions:
As a default strategy I would stick to the default of hover, imo this has the best balance between actually determining wether someone is going to visit a page and not overfetching.
No I dont think so :) I think the prefetching on hover will also optimize these links and adding [data-astro-prefetch="load"] will just lead to more overfetching. |
Okay, agreed we can limit default behaviour to With #242 nearly merged, we could use that setup to add an // Custom plugin to add ETag headers if missing
const addEtagPlugin = {
cacheWillUpdate: async ({ response }) => {
if (!response) return null;
const clonedResponse = response.clone();
// If response already has an ETag, return it unchanged
if (clonedResponse.headers.has('etag')) {
return clonedResponse;
}
// Generate ETag from response content
const content = await clonedResponse.clone().text();
const hash = await crypto.subtle.digest(
'SHA-1',
new TextEncoder().encode(content)
);
const etag = Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
// Create new response with ETag header
const newHeaders = new Headers(clonedResponse.headers);
newHeaders.set('etag', `"${etag}"`);
return new Response(content, {
status: clonedResponse.status,
statusText: clonedResponse.statusText,
headers: newHeaders,
});
}
};
registerRoute(
({ request }) => request.mode === 'navigate',
new NetworkFirst({
networkTimeoutSeconds: 3,
cacheName: 'pages',
plugins: [
addEtagPlugin,
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxEntries: 30,
}),
],
})
); @decrek what do you think? |
User stories
As a website visitor,
I want web pages to be prefetched,
so that navigation is instant when I hit a link.
As a website editor,
I want web pages to be cached only shortly,
so that the changes I make propagate reasonably quickly.
Approach
Use Astro's
prefetch
feature.Questions
hover
,tap
,viewport
,load
)?ETag
s, but we could add shortCache-Control
andExpires
headers either throughpublic/_headers
config or in a Service Worker (see Add Service Worker #199). Through a Service Worker we could even add our ownETag
s 🤔.hover
ortap
), should we add inline hints[data-astro-prefetch="load"]
to the main menu items (see Editable site menu #196)?The text was updated successfully, but these errors were encountered: