Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Load a Prism grammar only when a blob names it

1b8675b19e70346d6d02d5fc0c10538f50bf94b2 · Keenan Nemetz · 9d ago · parent 11720250

Load a Prism grammar only when a blob names it

The worker imported prism-languages.min.js — every grammar Prism ships — on
every code page. That is 546 KB to evaluate before the first token, and a page
showing one Go file paid it for all 293 components.

Each component is now vendored as its own file, and prism-manifest.js maps a
language name to the files that define it in dependency order. The worker
starts with Prism's core and the manifest and imports a language's files the
first time a job names it, remembering what it has run so a file is never
imported twice. A Go blob loads 30 KB instead of 564 KB; a .tsx blob, the
widest common entry at 8 files, loads 49 KB.

The manifest also carries the components that register no language of their
own but change one: css-extras, js-extras, js-templates, php-extras, xml-doc.
Each is placed after the grammar it rewrites and included in the entries that
inherit it, so a language that extends javascript now gets js-extras' arrow
and maybe-class-name tokens too. The old bundle's order handed those to some
inheriting languages and not others; nothing loses a token.

scripts/vendor-prism.py writes the grammars and the manifest, and --check
compares them byte for byte with cdnjs. TestPrismLanguagesAreVendored,
TestPrismGrammarsMatchTheManifest and TestPrismWorkerLoadsGrammarsOnDemand
hold the server's extension table, the vendored set and the worker's lazy
import together.

server/web/highlight.go +6−2

@@ -5,6 +5,10 @@ package web
5 5 // and does no lexing work per blob, and a file whose language is not in the
6 6 // table below is served as plain text with its line numbers — the honest result
7 7 // for a file we cannot classify.
8 //
9 // The worker loads a grammar when a blob first names it (static/prism-manifest.js
10 // and static/prism-languages/), so the table is also what decides which of
11 // Prism's grammars a page ever reads.
8 12
9 13 import (
10 14 "path"
@@ -14,8 +18,8 @@ import (
14 18 // prismLanguages maps a lower-case file extension (without the dot) or a whole
15 19 // lower-case file name to the Prism language that colours it. Prism has no file
16 20 // extension table of its own, so this is the work its grammars cannot do: every
17 // language in static/prism-languages.min.js is reachable from here, and a name
18 // this table does not claim stays plain.
21 // language the manifest can load is reachable from here, and a name this table
22 // does not claim stays plain.
19 23 //
20 24 // Names are matched before extensions because a Dockerfile has no extension and
21 25 // nginx.conf would otherwise be read as an ini file. Where two languages want