Prerequisites
Describe the issue
Some Go files freeze the browser tab when they render in a diff. I tracked it down to syntax highlighting: shiki runs into catastrophic backtracking on Go anonymous-struct fields (struct{}) when the struct tag has a long unbroken run of non-whitespace characters.
The cause is the pinned shiki version. @pierre/diffs requires shiki ^3.0.0, which installs 3.23.0. Its default shiki-js engine converts the Go grammar's struct_variables_types_fields rule (which uses \S+) into a JS RegExp that backtracks exponentially. shiki tracked the same problem in shikijs/shiki#1026.
The cost climbs fast with the length of that non-whitespace run: roughly 190ms at 20 chars, 4.6s at 25, and it never returns past about 30. A field that isn't struct{} doesn't hit it.
Reproduction
Stackblitz
import { CodeView } from "@pierre/diffs/react";
import type { CodeViewFileItem } from "@pierre/diffs";
// Go anonymous-struct field with one long no-space struct tag.
const contents = "type T struct {\n\tX struct{} `" + "x".repeat(40) + "`\n}\n";
const exampleItem: CodeViewFileItem = {
id: "foo",
type: "file",
file: { name: "x.go", contents },
};
function App() {
return (
<CodeView
items={[exampleItem]}
style={{ height: 600, overflow: "auto" }}
// Uncomment to confirm the cause (Oniguruma engine renders instantly):
// options={{ preferredHighlighter: "shiki-wasm" }}
/>
);
}
export default App;
Expected: highlights in a few ms.
Actual: the tab hangs on load (main-thread catastrophic backtracking). Shrinking the "x".repeat(40) shows the exponential curve: ~20 ≈ 190 ms, ~25 ≈ 4.6 s, ~30+ never returns. Switching to shiki-wasm allows the page to render.
What browser(s) are you seeing the problem on?
Chrome
What version of @pierre/diffs are you using?
1.2.5 (also 1.2.9 / 1.3.0-beta.4)
AI disclosure: issue written with assistance from Claude Opus 4.8 based on usage in my private codebase.
Prerequisites
Describe the issue
Some Go files freeze the browser tab when they render in a diff. I tracked it down to syntax highlighting: shiki runs into catastrophic backtracking on Go anonymous-struct fields (
struct{}) when the struct tag has a long unbroken run of non-whitespace characters.The cause is the pinned shiki version.
@pierre/diffsrequiresshiki ^3.0.0, which installs 3.23.0. Its defaultshiki-jsengine converts the Go grammar'sstruct_variables_types_fieldsrule (which uses\S+) into a JSRegExpthat backtracks exponentially. shiki tracked the same problem in shikijs/shiki#1026.The cost climbs fast with the length of that non-whitespace run: roughly 190ms at 20 chars, 4.6s at 25, and it never returns past about 30. A field that isn't
struct{}doesn't hit it.Reproduction
Stackblitz
Expected: highlights in a few ms.
Actual: the tab hangs on load (main-thread catastrophic backtracking). Shrinking the
"x".repeat(40)shows the exponential curve: ~20 ≈ 190 ms, ~25 ≈ 4.6 s, ~30+ never returns. Switching to shiki-wasm allows the page to render.What browser(s) are you seeing the problem on?
Chrome
What version of @pierre/diffs are you using?
1.2.5 (also 1.2.9 / 1.3.0-beta.4)
AI disclosure: issue written with assistance from Claude Opus 4.8 based on usage in my private codebase.