diff --git a/scripts/prose-matcher.js b/scripts/prose-matcher.js index 467f82b..a2ed298 100644 --- a/scripts/prose-matcher.js +++ b/scripts/prose-matcher.js @@ -65,12 +65,29 @@ const WORD_EDGE_END = /[\p{L}\p{N}]$/u; // Word boundaries only guard edges that are themselves word characters; // a punctuation-edged phrase keeps substring semantics on that side. +// +// Performance shape: the boundary regexes use Unicode property escapes, +// which are expensive to CONSTRUCT (measured ~0.3ms each; a 140-entry +// list paid ~40ms at startup). So each entry compiles its regex lazily, +// and matching prefilters with a cheap lowercase substring check first: +// the regex only ever confirms or rejects a substring hit, and a +// boundary match is always also a substring match, so semantics are +// unchanged. export function compilePhrases(list) { return list.map(({ bad, good }) => { - const escaped = bad.replace(RE_SPECIALS, '\\$&'); - const lead = WORD_EDGE.test(bad) ? '(?