Repository navigation
Conversation
|
Ran a comparison against #164 using a larger local xF sample. This genuinely replaces BBob with native markdown-it rules, and the mixed-Markdown improvements are real. The measurements show a modest overall speed improvement, rather than a substantially lighter payload, with several regressions worth fixing before merge. Tested revisions:
Corpus and measurements10,000 sampled xF posts + nine known complex reference posts, totaling 15.8 MB of message text. The sample used 64 bounded windows spread across the Each revision ran three times, sequentially with alternating order, through Discourse's actual JS cooking pipeline and sanitizer, with the same installed plugin features and real Ruby helper callbacks. Each run used an isolated MiniRacer/V8 context and a fresh Markdown engine per message. Timings exclude Rails startup, Ruby
Payload comparison uses the same Rails AMD transformation and Terser 5.51.2 compression/mangling, then gzip level 9. It includes the parser and its Markdown registration, excludes shared Discourse code/source maps, and is not a full production asset-download measurement. Heap numbers are retained-heap samples, not peak RSS. That is 11% less total rendering time, 3% fewer gzipped parser bytes, and essentially unchanged retained heap. The large-post subset took 34% longer, and the public Cyberkill reference post took 2.49× as long. Both revisions completed all 30,027 corpus renders each without exceptions. That does not establish content or visual equivalence for every historical post. Reproduced regressions1. Accordion delimiters inside inline code discard content#164 preserves
2. Unmatched-tag scanning scales quadraticallyReproducer: Five measurements per size produced these median rendering times:
The 4,000-tag input is only 16 kB. Doubling the input approaches quadrupling native rendering time. Each distinct opener gets a separate 3. Separate inline-code examples incorrectly suppress intervening BBCode#164 displays the two code examples and formats the intervening text red. #165 leaves Literal BBCode regions are indexed before inline-code spans, so these inactive delimiters become one false literal region. Confirmed with both single-line and multiline variants. scanner.js:303–338 4. Nested
|
|
Re-reviewed the updated branch and Tested revisions:
Status of the previous findings
Verified through the actual cooking pipeline, with browser checks for rendered output and mobile CSS. The broader worst-case scanning issue remains, despite the specific Remaining findings1. High: malformed-input performance still violates the stated 500,000-character goalFor
Doubling still approaches quadrupling. More decisively, Attribution matters: disabling this plugin reproduces most of the The plugin's literal-region scanner also still searches the remaining suffix repeatedly for unmatched literal tags. For 2. Medium: a new early return breaks valid containers inside Markdown quotesThe previous #165 revision renders a The new early return assumes removing blockquote markers cannot expose a close. It can: removing Retain the stripped-text fallback when Markdown transforms the line context. 3. Medium: an escaped backtick can now disable an accordionThere is exactly one backslash before the first backtick. The previous #165 revision recognizes the slide. The updated revision leaves the entire accordion literal. The literal-range scanner treats the escaped backtick as a code-span opener, hiding the only Honor Markdown escapes when indexing code spans, while retaining the protection for genuine inline-code examples. 4. Medium: keyboard activation of links inside inline spoilers is brokenReveal the spoiler, focus the link, and press Enter. The new keydown handler catches the link's bubbling event, prevents navigation, and closes the spoiler instead. Confirmed in Chromium with the actual old/new decorators on isolated markup: the old version follows the link; the updated version cancels the event. Separately confirmed that the actual cooker emits the anchor inside the inline spoiler. Only handle keyboard toggling when the spoiler itself is the event target, not an interactive descendant. 5. Medium: valid fractional animation keyframes are silently droppedThe new selector allowlist rejects The previous #165 cooker emits both frames, and Chromium recognizes Accept leading-dot decimal percentages without weakening the selector-injection protection. Updated performance comparisonReused the original 10,000 sampled xF posts plus nine reference posts, totaling 15.8 MB of message text. As in the prior review, this is a byte-stratified sample using 64 bounded windows across the SQL dump, not a uniform random sample of all posts. The figures below use three clean sequential runs per revision with alternating order, through Discourse's actual JS cooking pipeline and sanitizer, with the same installed plugin features and real Ruby helper callbacks. Each run used an isolated MiniRacer/V8 context and a fresh Markdown engine per message. Hardware: Ryzen 9 7950X / Linux x64.
That is approximately 16% faster overall, 24% faster on large posts, and 32% faster on Cyberkill. The previous large-post performance regression is reversed. The parser is now approximately 9% larger minified and 5% larger gzipped than #164, not lighter. Payloads were remeasured together using the same Rails AMD transformation, Terser 5.51.2 compression/mangling, and gzip level 9. This includes the parser and its Markdown registration, excludes shared Discourse code/source maps, and is not a full production asset-download measurement. Both revisions completed all 30,027 measured corpus renders each without exceptions. That does not establish content or visual equivalence across the corpus. Timings exclude Rails startup, Ruby Design decisions
The worst-case linearity and 500,000-character safety claims need correction until the remaining paths are addressed. Overall: the six targeted fixes and the performance improvement are real. I would address the five findings above before merging. No xF database restore/import, Discourse post writes, or rebake was performed. The sampled corpus stays private locally; the reproducers above are synthetic. |
Previously, BBob rendered the whole post to HTML before markdown-it ran, so bbcode broke core markdown and other Discourse features when mixed with them (headings, lists, polls, math,
[details], emphasis across tags), and unclosed or mis-nested tags lost content.This change parses bbcode as block, inline and core rules in the same markdown-it pass as core, so the two nest inside each other and render as XenForo did (every newline a
<br>, mis-nested tags closed with their parent). It also removes BBob and keeps<template>CSS/scripts and spoilers out of excerpts, emails and search.