diff --git a/.changeset/eleven-guests-rhyme.md b/.changeset/eleven-guests-rhyme.md new file mode 100644 index 000000000..183f73829 --- /dev/null +++ b/.changeset/eleven-guests-rhyme.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Updates `` component to cache and reuse Shiki highlighters diff --git a/packages/astro/components/Code.astro b/packages/astro/components/Code.astro index 32c441495..e829f87be 100644 --- a/packages/astro/components/Code.astro +++ b/packages/astro/components/Code.astro @@ -1,6 +1,6 @@ --- import type * as shiki from 'shiki'; -import { getHighlighter } from 'shiki'; +import { getHighlighter } from './Shiki.js'; export interface Props { /** The code to highlight. Required. */ diff --git a/packages/astro/components/Shiki.js b/packages/astro/components/Shiki.js new file mode 100644 index 000000000..9e8e60bc2 --- /dev/null +++ b/packages/astro/components/Shiki.js @@ -0,0 +1,22 @@ +import { getHighlighter as getShikiHighlighter } from 'shiki'; + +// Caches Promise for reuse when the same theme and langs are provided +const _resolvedHighlighters = new Map(); + +function stringify(opts) { + // Always sort keys before stringifying to make sure objects match regardless of parameter ordering + return JSON.stringify(opts, Object.keys(opts).sort()); +} + +export function getHighlighter(opts) { + const key = stringify(opts); + + // Highlighter has already been requested, reuse the same instance + if (_resolvedHighlighters.has(key)) { return _resolvedHighlighters.get(key) } + + // Start the async getHighlighter call and cache the Promise + const highlighter = getShikiHighlighter(opts); + _resolvedHighlighters.set(key, highlighter); + + return highlighter; +} \ No newline at end of file