Skip to content

Commit 16e6171

Browse files
authored
Cache embeds for faster rendering (#2488)
1 parent f885e88 commit 16e6171

File tree

3 files changed

+57
-18
lines changed

3 files changed

+57
-18
lines changed

.changeset/gentle-oranges-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'gitbook': patch
3+
---
4+
5+
Improve performances of loading pages with embeds by caching them

packages/gitbook/src/components/DocumentView/Embed.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Script from 'next/script';
44
import ReactDOM from 'react-dom';
55

66
import { Card } from '@/components/primitives';
7-
import { api } from '@/lib/api';
7+
import { getEmbedByUrlInSpace, getEmbedByUrl } from '@/lib/api';
88
import { tcls } from '@/lib/tailwind';
99

1010
import { BlockProps } from './Block';
@@ -17,9 +17,9 @@ export async function Embed(props: BlockProps<gitbookAPI.DocumentBlockEmbed>) {
1717

1818
ReactDOM.preload('https://cdn.iframe.ly/embed.js', { as: 'script', nonce });
1919

20-
const { data: embed } = await (context.content
21-
? api().spaces.getEmbedByUrlInSpace(context.content.spaceId, { url: block.data.url })
22-
: api().urls.getEmbedByUrl({ url: block.data.url }));
20+
const embed = await (context.content
21+
? getEmbedByUrlInSpace(context.content.spaceId, block.data.url)
22+
: getEmbedByUrl(block.data.url));
2323

2424
return (
2525
<Caption {...props}>

packages/gitbook/src/lib/api.ts

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,16 @@ export interface ContentTarget {
6464
}
6565

6666
/**
67-
* Parameter to cache an entry as an immutable one (ex: revisions, documents).
67+
* Parameter to cache an entry for a certain period of time.
6868
* It'll cache it for 1 week and revalidate it 24h before expiration.
6969
*
7070
* We don't cache for more than this to ensure we don't use too much storage and keep the cache small.
7171
*/
72-
const immutableCacheTtl_7days = {
72+
const cacheTtl_7days = {
7373
revalidateBefore: 24 * 60 * 60,
7474
ttl: 7 * 24 * 60 * 60,
7575
};
76-
const immutableCacheTtl_1day = {
76+
const cacheTtl_1day = {
7777
revalidateBefore: 60 * 60,
7878
ttl: 24 * 60 * 60,
7979
};
@@ -364,10 +364,7 @@ export const getRevision = cache({
364364
},
365365
);
366366

367-
return cacheResponse(
368-
response,
369-
fetchOptions.metadata ? immutableCacheTtl_7days : immutableCacheTtl_1day,
370-
);
367+
return cacheResponse(response, fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day);
371368
},
372369
getKeyArgs: (args) => [args[0], args[1]],
373370
});
@@ -398,7 +395,7 @@ export const getRevisionPages = cache({
398395
);
399396

400397
return cacheResponse(response, {
401-
...(fetchOptions.metadata ? immutableCacheTtl_7days : immutableCacheTtl_1day),
398+
...(fetchOptions.metadata ? cacheTtl_7days : cacheTtl_1day),
402399
data: response.data.pages,
403400
});
404401
},
@@ -434,12 +431,12 @@ export const getRevisionPageByPath = cache({
434431
},
435432
);
436433

437-
return cacheResponse(response, immutableCacheTtl_7days);
434+
return cacheResponse(response, cacheTtl_7days);
438435
} catch (error) {
439436
if ((error as GitBookAPIError).code === 404) {
440437
return {
441438
data: null,
442-
...immutableCacheTtl_7days,
439+
...cacheTtl_7days,
443440
};
444441
}
445442

@@ -478,10 +475,10 @@ const getRevisionFileById = cache({
478475
);
479476
})();
480477

481-
return cacheResponse(response, immutableCacheTtl_7days);
478+
return cacheResponse(response, cacheTtl_7days);
482479
} catch (error: any) {
483480
if (error instanceof GitBookAPIError && error.code === 404) {
484-
return { data: null, ...immutableCacheTtl_7days };
481+
return { data: null, ...cacheTtl_7days };
485482
}
486483

487484
throw error;
@@ -522,7 +519,7 @@ const getRevisionAllFiles = cache({
522519
files[file.id] = file;
523520
});
524521

525-
return cacheResponse(response, { ...immutableCacheTtl_7days, data: files });
522+
return cacheResponse(response, { ...cacheTtl_7days, data: files });
526523
},
527524
timeout: 60 * 1000,
528525
});
@@ -599,7 +596,7 @@ export const getDocument = cache({
599596
...noCacheFetchOptions,
600597
},
601598
);
602-
return cacheResponse(response, immutableCacheTtl_7days);
599+
return cacheResponse(response, cacheTtl_7days);
603600
},
604601
// Temporarily allow for a longer timeout than the default 10s
605602
// because GitBook's API currently re-normalizes all documents
@@ -1084,6 +1081,43 @@ export const renderIntegrationUi = cache({
10841081
},
10851082
});
10861083

1084+
/**
1085+
* Fetch an embed.
1086+
* We don't cache them by cache tag, as we never purge them (they expire after 7 days).
1087+
*/
1088+
export const getEmbedByUrl = cache({
1089+
name: 'api.getEmbedByUrl',
1090+
get: async (url: string, options: CacheFunctionOptions) => {
1091+
const response = await api().urls.getEmbedByUrl(
1092+
{ url },
1093+
{
1094+
...noCacheFetchOptions,
1095+
signal: options.signal,
1096+
},
1097+
);
1098+
return cacheResponse(response);
1099+
},
1100+
});
1101+
1102+
/**
1103+
* Fetch an embed in a space.
1104+
*/
1105+
export const getEmbedByUrlInSpace = cache({
1106+
name: 'api.getEmbedByUrlInSpace',
1107+
tag: (spaceId) => getAPICacheTag({ tag: 'space', space: spaceId }),
1108+
get: async (spaceId: string, url: string, options: CacheFunctionOptions) => {
1109+
const response = await api().spaces.getEmbedByUrlInSpace(
1110+
spaceId,
1111+
{ url },
1112+
{
1113+
...noCacheFetchOptions,
1114+
signal: options.signal,
1115+
},
1116+
);
1117+
return cacheResponse(response, cacheTtl_7days);
1118+
},
1119+
});
1120+
10871121
/**
10881122
* Create a cache tag for the API.
10891123
*/

0 commit comments

Comments
 (0)