Skip to content

Commit

Permalink
Perf: reuse Shiki highlighters per theme/lang (#3130)
Browse files Browse the repository at this point in the history
* reuse Shiki highlighters per theme/lang

* chore: adding changeset
  • Loading branch information
Tony Sullivan committed Apr 18, 2022
1 parent 9e35758 commit 394ab90
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/eleven-guests-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Updates `<Code />` component to cache and reuse Shiki highlighters
2 changes: 1 addition & 1 deletion packages/astro/components/Code.astro
Original file line number Diff line number Diff line change
@@ -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. */
Expand Down
22 changes: 22 additions & 0 deletions packages/astro/components/Shiki.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getHighlighter as getShikiHighlighter } from 'shiki';

// Caches Promise<Highligher> 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;
}

0 comments on commit 394ab90

Please sign in to comment.