A client-side page on webperf-snippets that accepts the JSON return value of any snippet (copied from the browser console), detects the snippet type, and renders a formatted performance report.
Problem solved: Sites protected by Akamai or strict CSP block extended DevTools console output, but the IIFE return value remains accessible as the last evaluated expression. The visualizer turns that object into a readable report without requiring any setup or CLI.
Target users: Web performance engineers doing reviews on sites with restrictive security policies (e.g., FedEx, enterprise sites with Akamai).
- Paste area — textarea accepting a raw JSON object (single result, not array)
- Auto-parse — live parse on input change (debounced 300ms); no submit button
- Auto-detect — identify snippet type from the
scriptfield (or structural heuristics) - Renderers — three display modes:
- CWV — metric + rating + value + optional LCP subparts
- Fonts — loaded fonts table, used-above-fold table, issues
- Audit — issues list (severity-colored) + items table (generic)
- Export as Markdown — copy the rendered report as Markdown to clipboard
- Error state — clear message for invalid JSON or unrecognized format
- Pasting a Fonts snippet result renders three sections: Loaded, Used above fold, Issues
- Pasting an LCP result shows rating badge + value + subParts breakdown when present
- Pasting any audit snippet result shows issues list + items table (up to 10 rows)
- Pasting invalid JSON shows an inline error, not a crash
- "Copy as Markdown" copies formatted Markdown to clipboard and shows confirmation
- Page appears in the sidebar nav as "Visualizer"
- No new npm dependencies introduced
result.script === "Fonts-Preloaded-Loaded-and-used-above-the-fold" → FontsRenderer
result.rating != null → CWVRenderer
Array.isArray(result.issues) → AuditRenderer
otherwise → RawRenderer (formatted JSON)
CWV metric (LCP, CLS, INP, FCP, etc.):
{
"script": "LCP",
"metric": "LCP",
"rating": "good | needs-improvement | poor",
"value": 1234,
"unit": "ms | score",
"details": { "element": "...", "subParts": { "ttfb": {}, ... } }
}Fonts:
{
"script": "Fonts-Preloaded-Loaded-and-used-above-the-fold",
"status": "ok",
"details": { "preloadedCount": 2, "loadedCount": 3, "usedAboveFoldCount": 2, ... },
"items": [{ "family": "...", "weight": "400", "style": "normal", "display": "swap" }],
"usedFonts": [{ "family": "...", "weight": "400", "style": "normal", "elements": 12 }],
"issues": [{ "severity": "warning | error", "message": "..." }]
}Audit (all other snippets):
{
"script": "Find-render-blocking-resources",
"status": "ok",
"count": 3,
"items": [{ "url": "...", "type": "script", "durationMs": 120 }],
"issues": [{ "severity": "error | warning | info", "message": "..." }]
}pages/
visualizer.mdx ← Nextra page (imports SnippetVisualizer)
components/
SnippetVisualizer.jsx ← Main component (textarea + renderer dispatch)
SnippetVisualizer/
CWVRenderer.jsx
FontsRenderer.jsx
AuditRenderer.jsx
exportMarkdown.js ← Pure function: result → markdown string
pages/_meta.json gets a new entry:
"visualizer": { "title": "Visualizer" }- No new dependencies — React hooks only (
useState,useMemo,useCallback) - CSS classes — Nextra
nx-utility classes for visual consistency; inline styles only for dynamic values (rating colors) - No TypeScript — plain
.jsx/.js, matching the rest of the project - No comments unless the why is non-obvious
Single result exported as:
## Fonts — Fonts-Preloaded-Loaded-and-used-above-the-fold
### Loaded Fonts
| Family | Weight | Style | Display |
|--------|--------|-------|---------|
| ... | 400 | normal| swap |
### Used Above Fold
| Family | Weight | Style | Elements |
...
### Issues
- ⚠️ warning: Font preloaded without crossorigin...For CWV metrics:
## LCP — 1.2s ✅ good
...| Always | Ask First | Never |
|---|---|---|
| Handle invalid input gracefully | Adding a new npm dependency | Server-side code / API routes |
| Keep all logic client-side | Changing next.config.js | TypeScript migration |
Use nx- classes for styling |
Adding a new page category | Storing paste data anywhere |
| Clear error feedback | Sending data to any external service |