Skip to content

Commit

Permalink
feat: cache getCollection() calls in production (#6503)
Browse files Browse the repository at this point in the history
* feat: cache getCollection() in prod

* chore: changeset
  • Loading branch information
bholmesdev committed Mar 10, 2023
1 parent c44aa15 commit f6eddff
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-cougars-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Add caching to `getCollection()` queries for faster SSG production builds
49 changes: 29 additions & 20 deletions packages/astro/src/content/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function createCollectionToGlobResultMap({
return collectionToGlobResultMap;
}

const cacheEntriesByCollection = new Map<string, any[]>();
export function createGetCollection({
collectionToEntryMap,
collectionToRenderEntryMap,
Expand All @@ -47,27 +48,35 @@ export function createGetCollection({
}) {
return async function getCollection(collection: string, filter?: (entry: any) => unknown) {
const lazyImports = Object.values(collectionToEntryMap[collection] ?? {});
const entries = Promise.all(
lazyImports.map(async (lazyImport) => {
const entry = await lazyImport();
return {
id: entry.id,
slug: entry.slug,
body: entry.body,
collection: entry.collection,
data: entry.data,
async render() {
return render({
collection: entry.collection,
id: entry.id,
collectionToRenderEntryMap,
});
},
};
})
);
let entries: any[] = [];
// Cache `getCollection()` calls in production only
// prevents stale cache in development
if (import.meta.env.PROD && cacheEntriesByCollection.has(collection)) {
entries = cacheEntriesByCollection.get(collection)!;
} else {
entries = await Promise.all(
lazyImports.map(async (lazyImport) => {
const entry = await lazyImport();
return {
id: entry.id,
slug: entry.slug,
body: entry.body,
collection: entry.collection,
data: entry.data,
async render() {
return render({
collection: entry.collection,
id: entry.id,
collectionToRenderEntryMap,
});
},
};
})
);
cacheEntriesByCollection.set(collection, entries);
}
if (typeof filter === 'function') {
return (await entries).filter(filter);
return entries.filter(filter);
} else {
return entries;
}
Expand Down

0 comments on commit f6eddff

Please sign in to comment.