@@ -134,7 +134,9 @@ public/ # static files copied verbatim into out/:
134134 repositories.txt # synced from the repo root (sync-repositories.mjs)
135135 assets/ # mustache template, logo
136136 templates/ # workflow-sample-*.html fragments
137- widgets/ # module bridges: vizdom WASM, three-spritetext,
137+ widgets/ # module bridges: vizdom WASM, force-graph
138+ # (3D graph + sprite labels sharing one
139+ # three build),
138140 # sentry (runtime CDN imports cannot be bundled)
139141templates/ # user CI samples (user-refactorfirst-*.yml) for the docs
140142ci/process-submissions.sh # shared submission validator for GH/Gl/BB CI
@@ -256,14 +258,30 @@ coverage there when introducing new markup patterns.
256258 lib/renderer.js applies ** filter → sort → paginate** per table and injects
257259 ` tableUi ` blocks the mustache template renders; ` enhanceTables ` in
258260 lib/table-enhancer.js binds the controls and reports state changes back to
259- components/report-view.jsx, which re-renders (widgets only gate the first
260- render; the search input's focus/caret is restored after each re-render).
261- The expensive ` enhanceReport ` pipeline (Chart.js charts, WASM DOT layout)
262- runs only when the payload changes — table-state re-renders stash the live
263- chart canvases / graph containers before the innerHTML swap and graft them
264- back into the fresh DOM (` statefulElementIds ` /` stashStatefulDom ` /
265- ` graftStatefulDom ` in lib/report-view.js), re-binding only the cheap popup
266- handlers.
261+ components/report-view.jsx, which re-renders (widgets never gate the
262+ render — charts/graphs enhance progressively via ` onWidgetReady `
263+ callbacks when their widget reports ready; the search input's focus/caret
264+ is restored after each re-render). The expensive ` enhanceReport ` pipeline
265+ (Chart.js charts, WASM DOT layout) runs only when the payload changes —
266+ it receives ` {charts, graphs} ` readiness flags so still-loading widgets
267+ are skipped and picked up by the widget-readiness effect instead — and
268+ table-state re-renders stash the live chart canvases / graph containers
269+ before the innerHTML swap and graft them back into the fresh DOM
270+ (` statefulElementIds ` /` stashStatefulDom ` /` graftStatefulDom ` in
271+ lib/report-view.js), re-binding only the cheap popup handlers.
272+ - Initial render performance (LCP/CLS): the report markup renders as soon
273+ as the parallel template + report-JSON fetches resolve, never waiting on
274+ the CDN widgets or the ~ 4.8MB vizdom wasm. The report page shells
275+ (` [username]/[repository]/page.jsx ` + ` [branch]/page.jsx ` ) preconnect to
276+ raw.githubusercontent.com (the report JSON host; CORS fetch) and
277+ cdnjs.cloudflare.com (classic widget scripts) and render the loading
278+ placeholder inside ` #report-container ` — the same id the hydrated
279+ ReportView renders — with a full-viewport ` min-height: 100svh ` (vh
280+ fallback) in app/globals.css, so the footer starts below the fold and
281+ the report's arrival causes no layout shift. The vizdom bridge
282+ (` public/widgets/vizdom-bridge.js ` ) serves the wasm from Cache Storage
283+ (versioned cache name) so repeat visits never re-download it regardless
284+ of the host's HTTP cache headers.
267285- Search ` <input> ` s are injected by table-enhancer — ` <input> ` is FORBID in
268286 the renderer's sanitization allow-list, so it must never appear in the
269287 mustache template.
0 commit comments