Commit Graph
5 Commits
Author SHA1 Message Date
50468f9c90 perf(explorer): stop re-parsing markdown on every viewer re-render (#1118) (#1195)
Profiling the viewer in headless Chromium (real DOM, production React)
separated remark parse time, React commit time and DOM node count across
large-prose, large-code-block, deep-nested-list and GFM-table fixtures.

Two findings, one of which is fixed here.

1. Every re-render re-parsed the whole document and remounted the whole
   subtree. remarkPlugins and the ~20-entry components map were inline
   literals, so each render allocated fresh arrow components; React saw a new
   element type per mapped tag and replaced the DOM rather than updating it. A
   DOM-identity probe confirmed the remount on every fixture. Because
   react-markdown runs the remark pipeline inside its own render, an unrelated
   state change -- clicking Copy, toggling Preview/Source -- re-paid the full
   parse. Measured 364ms for a 1000-row GFM table and 1121ms for 2000 rows.

   Hoisting both props to module scope and memoising the rendered element on
   rawContent drops re-render cost to ~0.1ms across every fixture and removes
   the remount (DOM identity now survives). Initial mount and node switching
   are unchanged, since those are genuine parses.

2. Initial parse of large GFM tables is quadratic and lives upstream in
   remark-gfm: the same table text parses in 12.5ms without the plugin and
   1156ms with it at 2000 rows. Not addressed here -- any mitigation is a
   product decision and is tracked on the issue.

Note that document size is the wrong threshold for this: 562KB of prose parses
in 85ms while a 27KB GFM table takes 102ms. Row count, not bytes, predicts cost.

Rendered output is unchanged; the components map is moved verbatim. All 66
Explorer graph-workspace tests pass.

Co-authored-by: Pravit Ampapathini <pravit.amp@gmail.com>
Co-authored-by: Sameer Kadam <sskadam6305@gmail.com>
2026-08-25 19:44:47 +05:30
pravit-ampandPravit Ampapathini c7d608570c refactor(explorer): move isSafeUrl out of MarkdownContentViewer (#1119) (#1194)
MarkdownContentViewer.tsx exported the isSafeUrl helper alongside the
component so it could be unit tested, which tripped
react-refresh/only-export-components.

Move the helper into a sibling pure module, markdownUrlSafety.ts,
following the existing GraphWorkspace convention for testable non-component
logic (graphAnalytics.ts, pluginRegistryPredicates.ts,
temporalLifecyclePredicates.ts). The function body is moved verbatim — the
scheme allowlist, protocol-relative rejection, whitespace-only guard and
malformed-URL handling are unchanged — so the existing URL-safety tests pass
untouched apart from the import path.

The component module now exports only its component and prop type, clearing
the lint error without any change to the lint configuration.

Co-authored-by: Pravit Ampapathini <pravit.amp@gmail.com>
2026-08-25 16:32:34 +05:00
Sameer6305 7b2b2efe6b fix(explorer): harden markdown viewer review findings 2026-08-19 15:37:12 +05:30
Sakshi Jain 5a3bdc393d fix(explorer): address review feedback on markdown viewer 2026-08-19 09:58:17 +05:30
Sakshi Jain 0f308b2078 feat(explorer): add markdown content preview and source view 2026-08-18 12:04:53 +05:30