Why
static/prism-worker.js imported prism-languages.min.js — every grammar
Prism ships — on every code page. That is 546 KB the browser evaluates before it
can colour the first line, and a page showing one Go file paid for all 293
components. The server still carries no lexer; only the amount of JavaScript the
browser parses changes.
What
static/prism-languages/<component>.jsholds one Prism component per file, byte for byte as cdnjs serves it.static/prism-manifest.jsmaps a language name to the files that define it, in dependency order (php→ markup-templating, php;scala→ java, scala).- The worker starts with
prism.min.jsand the manifest, and imports a language’s files the first time a job names it. A file that has been run is never imported again, because a secondinsertBeforewould insert the same grammar twice. scripts/vendor-prism.pygenerates all of it and--checkcompares the committed bytes with cdnjs. It refuses to generate if a component ends up imported by no entry, so a language Prism adds cannot silently go missing.
A Go blob now loads 30 KB instead of 564 KB; php 37 KB, csharp 36 KB, and
.tsx 49 KB over 8 files, the widest common entry.
Behaviour to review
Five components register no language of their own but change one: css-extras,
js-extras, js-templates, php-extras, xml-doc. The manifest carries them
in the entries that inherit the grammar they rewrite, placed right after it.
That makes one deliberate difference from the old bundle, whose order handed
js-extras to some languages that extend javascript and not others:
actionscript, coffee, coffeescript, flow, ts, tsx and typescript
gain arrow/control-flow/maybe-class-name tokens. Comparing all 395
language names old against new, those seven gain token classes and nothing
loses any.
js-templates decides which languages it can embed inside a template string
when it loads, so the grammars it embeds (sql, graphql, markdown) are
loaded just before it. Without that the highlighting of a sql`…` literal
would depend on what else the page had read first.
Checks
vole workflow run verify— all steps pass, includinggo test -race ./..., the license and link checks, and packaging.python3 scripts/vendor-prism.py --check— the vendored grammars and manifest match Prism 1.30.0 on cdnjs (387 names, 293 components).- Every manifest entry was loaded and tokenised in a Node harness that stubs
importScripts, with no exceptions and no entry answering plain.
Not in this change
Markdown fenced code blocks are the reason to want the manifest, but wiring
class="language-…" through the sanitizer and app.js is a separate change.
A SharedWorker is also deferred: with grammars loaded on demand, the remaining
per-navigation cost is one small import.